diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 20:45:01 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-07 20:45:01 +0000 |
commit | 4bce24e4288130d9436863d1db3ee0295ed93277 (patch) | |
tree | 41b08178a03d6233ada409e877c5160ebabc189c | |
parent | 1fc82d9171749533e7028a21c1649697499f6056 (diff) | |
download | chromium_src-4bce24e4288130d9436863d1db3ee0295ed93277.zip chromium_src-4bce24e4288130d9436863d1db3ee0295ed93277.tar.gz chromium_src-4bce24e4288130d9436863d1db3ee0295ed93277.tar.bz2 |
Added GPU stat for whether a GPU can report context lost.
On Windows it checks to see if the IDirect3D9 object supports Vista and later features (meaning it won't routinely report lost contexts). On Linux and Mac we can just check if its EGL versus some other GL that doesn't report lost contexts.
I routed the stats to the renderer process so webkit code can query whether lost contexts are likely.
I didn't wire up breakpad yet.
TEST=try
BUG=52318
Review URL: http://codereview.chromium.org/3149016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58755 0039d316-1c4b-4281-b951-d872f2087c98
25 files changed, 339 insertions, 186 deletions
diff --git a/app/gfx/gl/gl_context_egl.cc b/app/gfx/gl/gl_context_egl.cc index 7cfde87..1156635 100644 --- a/app/gfx/gl/gl_context_egl.cc +++ b/app/gfx/gl/gl_context_egl.cc @@ -85,6 +85,10 @@ bool BaseEGLContext::InitializeOneOff() { return true; } +EGLDisplay BaseEGLContext::GetDisplay() { + return g_display; +} + NativeViewEGLContext::NativeViewEGLContext(void* window) : window_(window), surface_(NULL), diff --git a/app/gfx/gl/gl_context_egl.h b/app/gfx/gl/gl_context_egl.h index 3f1884b..9c59825 100644 --- a/app/gfx/gl/gl_context_egl.h +++ b/app/gfx/gl/gl_context_egl.h @@ -9,7 +9,8 @@ #include "gfx/size.h" #include "app/gfx/gl/gl_context.h" -typedef void *EGLContext; +typedef void* EGLDisplay; +typedef void* EGLContext; typedef void* EGLSurface; namespace gfx { @@ -26,6 +27,8 @@ class BaseEGLContext : public GLContext { static bool InitializeOneOff(); + static EGLDisplay GetDisplay(); + private: DISALLOW_COPY_AND_ASSIGN(BaseEGLContext); }; diff --git a/chrome/browser/gpu_process_host.cc b/chrome/browser/gpu_process_host.cc index 67f9b56..fe212e9 100644 --- a/chrome/browser/gpu_process_host.cc +++ b/chrome/browser/gpu_process_host.cc @@ -14,6 +14,7 @@ #include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/gpu_info.h" #include "chrome/common/gpu_messages.h" #include "chrome/common/render_messages.h" #include "ipc/ipc_channel_handle.h" @@ -148,7 +149,7 @@ void GpuProcessHost::EstablishGpuChannel(int renderer_id, if (Send(new GpuMsg_EstablishChannel(renderer_id))) { sent_requests_.push(ChannelRequest(filter)); } else { - ReplyToRenderer(IPC::ChannelHandle(), filter); + ReplyToRenderer(IPC::ChannelHandle(), GPUInfo(), filter); } } @@ -182,7 +183,7 @@ void GpuProcessHost::OnChannelEstablished( const IPC::ChannelHandle& channel_handle, const GPUInfo& gpu_info) { const ChannelRequest& request = sent_requests_.front(); - ReplyToRenderer(channel_handle, request.filter); + ReplyToRenderer(channel_handle, gpu_info, request.filter); sent_requests_.pop(); gpu_info_ = gpu_info; child_process_logging::SetGpuInfo(gpu_info); @@ -288,9 +289,10 @@ void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( void GpuProcessHost::ReplyToRenderer( const IPC::ChannelHandle& channel, + const GPUInfo& gpu_info, ResourceMessageFilter* filter) { ViewMsg_GpuChannelEstablished* message = - new ViewMsg_GpuChannelEstablished(channel); + new ViewMsg_GpuChannelEstablished(channel, gpu_info); // If the renderer process is performing synchronous initialization, // it needs to handle this message before receiving the reply for // the synchronous ViewHostMsg_SynchronizeGpu message. diff --git a/chrome/browser/gpu_process_host.h b/chrome/browser/gpu_process_host.h index cfb2821..b1b1b75 100644 --- a/chrome/browser/gpu_process_host.h +++ b/chrome/browser/gpu_process_host.h @@ -16,6 +16,7 @@ #include "gfx/native_widget_types.h" struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params; +class GPUInfo; namespace IPC { struct ChannelHandle; @@ -96,6 +97,7 @@ class GpuProcessHost : public BrowserChildProcessHost { #endif void ReplyToRenderer(const IPC::ChannelHandle& channel, + const GPUInfo& gpu_info, ResourceMessageFilter* filter); // ResourceDispatcherHost::Receiver implementation: diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index d77eb43..8851192 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -726,6 +726,8 @@ 'conditions': [ ['OS=="win"', { 'include_dirs': [ + '<(DEPTH)/third_party/angle/include', + '<(DEPTH)/third_party/angle/src', '<(DEPTH)/third_party/wtl/include', ], 'dependencies': [ diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 7a864da..b0c4547 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -63,6 +63,7 @@ 'common/gpu_messages.cc', 'common/gpu_messages.h', 'common/gpu_messages_internal.h', + 'common/gpu_param_traits.h', 'common/gpu_video_common.cc', 'common/gpu_video_common.h', 'common/indexed_db_key.cc', diff --git a/chrome/common/gpu_info.cc b/chrome/common/gpu_info.cc index 6ba16d6..4fcd6a4 100644 --- a/chrome/common/gpu_info.cc +++ b/chrome/common/gpu_info.cc @@ -6,8 +6,10 @@ GPUInfo::GPUInfo() : vendor_id_(0), device_id_(0), driver_version_(L""), - pixel_shader_version_(0), vertex_shader_version_(0), - gl_version_(0) { + pixel_shader_version_(0), + vertex_shader_version_(0), + gl_version_(0), + can_lose_context_(false) { } uint32 GPUInfo::vendor_id() const { @@ -35,15 +37,21 @@ uint32 GPUInfo::gl_version() const { } +bool GPUInfo::can_lose_context() const { + return can_lose_context_; +} + void GPUInfo::SetGraphicsInfo(uint32 vendor_id, uint32 device_id, const std::wstring& driver_version, uint32 pixel_shader_version, uint32 vertex_shader_version, - uint32 gl_version) { + uint32 gl_version, + bool can_lose_context) { vendor_id_ = vendor_id; device_id_ = device_id; driver_version_ = driver_version; pixel_shader_version_ = pixel_shader_version; vertex_shader_version_ = vertex_shader_version; gl_version_ = gl_version; + can_lose_context_ = can_lose_context; } diff --git a/chrome/common/gpu_info.h b/chrome/common/gpu_info.h index 1280a51..a3aafe2 100644 --- a/chrome/common/gpu_info.h +++ b/chrome/common/gpu_info.h @@ -46,12 +46,17 @@ class GPUInfo { // D3D instead. uint32 gl_version() const; + // Return the device semantics, i.e. whether the Vista and Windows 7 specific + // semantics are available. + bool can_lose_context() const; + // Populate variables with passed in values void SetGraphicsInfo(uint32 vendor_id, uint32 device_id, const std::wstring& driver_version, uint32 pixel_shader_version, uint32 vertex_shader_version, - uint32 gl_version); + uint32 gl_version, + bool can_lose_context); private: uint32 vendor_id_; uint32 device_id_; @@ -59,6 +64,7 @@ class GPUInfo { uint32 pixel_shader_version_; uint32 vertex_shader_version_; uint32 gl_version_; + bool can_lose_context_; }; #endif // CHROME_COMMON_GPU_INFO_H__ diff --git a/chrome/common/gpu_messages.cc b/chrome/common/gpu_messages.cc index 61920cc..34f051c 100644 --- a/chrome/common/gpu_messages.cc +++ b/chrome/common/gpu_messages.cc @@ -13,41 +13,141 @@ "chrome/common/gpu_messages_internal.h" #include "ipc/ipc_message_impl_macros.h" +#if defined(OS_MACOSX) + +// Parameters for the GpuHostMsg_AcceleratedSurfaceSetIOSurface +// message, which has too many parameters to be sent with the +// predefined IPC macros. +GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params:: + GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params() + : renderer_id(0), + render_view_id(0), + window(NULL), + width(0), + height(0), + identifier(0) { +} + +#endif + namespace IPC { -void ParamTraits<GPUInfo>::Write(Message* m, const param_type& p) { +#if defined(OS_MACOSX) + +void ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> ::Write( + Message* m, + const param_type& p) { + WriteParam(m, p.renderer_id); + WriteParam(m, p.render_view_id); + WriteParam(m, p.window); + WriteParam(m, p.width); + WriteParam(m, p.height); + WriteParam(m, p.identifier); +} + +bool ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> ::Read( + const Message* m, + void** iter, + param_type* p) { + return ReadParam(m, iter, &p->renderer_id) && + ReadParam(m, iter, &p->render_view_id) && + ReadParam(m, iter, &p->window) && + ReadParam(m, iter, &p->width) && + ReadParam(m, iter, &p->height) && + ReadParam(m, iter, &p->identifier); +} + +void ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> ::Log( + const param_type& p, + std::string* l) { + l->append("("); + LogParam(p.renderer_id, l); + l->append(", "); + LogParam(p.render_view_id, l); + l->append(", "); + LogParam(p.window, l); + l->append(", "); + LogParam(p.width, l); + l->append(", "); + LogParam(p.height, l); + l->append(", "); + LogParam(p.identifier, l); + l->append(")"); +} + +#endif // if defined(OS_MACOSX) + +void ParamTraits<GPUInfo> ::Write(Message* m, const param_type& p) { 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()); } -bool ParamTraits<GPUInfo>::Read(const Message* m, void** iter, param_type* p) { +bool ParamTraits<GPUInfo> ::Read(const Message* m, void** iter, param_type* p) { uint32 vendor_id; uint32 device_id; std::wstring driver_version; uint32 pixel_shader_version; uint32 vertex_shader_version; uint32 gl_version; + bool can_lose_context; bool 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); - p->SetGraphicsInfo(vendor_id, device_id, driver_version, - pixel_shader_version, vertex_shader_version, - gl_version); + ret = ret && m->ReadBool(iter, &can_lose_context); + p->SetGraphicsInfo(vendor_id, + device_id, + driver_version, + pixel_shader_version, + vertex_shader_version, + gl_version, + can_lose_context); return ret; } -void ParamTraits<GPUInfo>::Log(const param_type& p, std::string* l) { - l->append(StringPrintf("<GPUInfo> %x %x %ls", +void ParamTraits<GPUInfo> ::Log(const param_type& p, std::string* l) { + l->append(StringPrintf("<GPUInfo> %x %x %ls %d", p.vendor_id(), p.device_id(), - p.driver_version().c_str())); + p.driver_version().c_str(), + p.can_lose_context())); +} + +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); +} + +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)) { + p->error = static_cast<gpu::error::Error>(temp); + return true; + } else { + return false; + } +} + +void ParamTraits<gpu::CommandBuffer::State> ::Log(const param_type& p, + std::string* l) { + l->append("<CommandBuffer::State>"); } } // namespace IPC diff --git a/chrome/common/gpu_messages.h b/chrome/common/gpu_messages.h index fd0583c..799bc98 100644 --- a/chrome/common/gpu_messages.h +++ b/chrome/common/gpu_messages.h @@ -10,110 +10,10 @@ #include "base/process.h" #include "chrome/common/common_param_traits.h" #include "chrome/common/gpu_native_window_handle.h" +#include "chrome/common/gpu_param_traits.h" #include "gfx/native_widget_types.h" #include "gpu/command_buffer/common/command_buffer.h" -class GPUInfo; - -#if defined(OS_MACOSX) -// Parameters for the GpuHostMsg_AcceleratedSurfaceSetIOSurface -// message, which has too many parameters to be sent with the -// predefined IPC macros. -struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params { - int32 renderer_id; - int32 render_view_id; - gfx::PluginWindowHandle window; - int32 width; - int32 height; - uint64 identifier; - - GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params() - : renderer_id(0), - render_view_id(0), - window(NULL), - width(0), - height(0), - identifier(0) { - } -}; -#endif - -namespace IPC { -#if defined(OS_MACOSX) -template <> -struct ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> { - typedef GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params param_type; - static void Write(Message* m, const param_type& p) { - WriteParam(m, p.renderer_id); - WriteParam(m, p.render_view_id); - WriteParam(m, p.window); - WriteParam(m, p.width); - WriteParam(m, p.height); - WriteParam(m, p.identifier); - } - static bool Read(const Message* m, void** iter, param_type* p) { - return ReadParam(m, iter, &p->renderer_id) && - ReadParam(m, iter, &p->render_view_id) && - ReadParam(m, iter, &p->window) && - ReadParam(m, iter, &p->width) && - ReadParam(m, iter, &p->height) && - ReadParam(m, iter, &p->identifier); - } - static void Log(const param_type& p, std::string* l) { - l->append("("); - LogParam(p.renderer_id, l); - l->append(", "); - LogParam(p.render_view_id, l); - l->append(", "); - LogParam(p.window, l); - l->append(", "); - LogParam(p.width, l); - l->append(", "); - LogParam(p.height, l); - l->append(", "); - LogParam(p.identifier, l); - l->append(")"); - } -}; -#endif - -template <> -struct ParamTraits<GPUInfo> { - typedef GPUInfo 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) { - m->WriteInt(p.num_entries); - m->WriteInt(p.get_offset); - m->WriteInt(p.put_offset); - m->WriteInt(p.token); - m->WriteInt(p.error); - } - static bool 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)) { - p->error = static_cast<gpu::error::Error>(temp); - return true; - } else { - return false; - } - } - static void Log(const param_type& p, std::string* l) { - l->append("<CommandBuffer::State>"); - } -}; -} // namespace IPC - #define MESSAGES_INTERNAL_FILE \ "chrome/common/gpu_messages_internal.h" #include "ipc/ipc_message_macros.h" diff --git a/chrome/common/gpu_messages_unittest.cc b/chrome/common/gpu_messages_unittest.cc index cf7408f..41a33ef 100644 --- a/chrome/common/gpu_messages_unittest.cc +++ b/chrome/common/gpu_messages_unittest.cc @@ -15,8 +15,10 @@ TEST(GPUIPCMessageTest, GPUInfo) { GPUInfo input; // Test variables taken from Lenovo T61 input.SetGraphicsInfo(0x10de, 0x429, L"6.14.11.7715", - 0xffff0300, 0xfffe0300, - 0x00010005); + 0xffff0300, + 0xfffe0300, + 0x00010005, + true); IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL); IPC::WriteParam(&msg, input); @@ -30,8 +32,9 @@ TEST(GPUIPCMessageTest, GPUInfo) { EXPECT_EQ(input.pixel_shader_version(), output.pixel_shader_version()); EXPECT_EQ(input.vertex_shader_version(), output.vertex_shader_version()); EXPECT_EQ(input.gl_version(), output.gl_version()); + EXPECT_EQ(input.can_lose_context(), output.can_lose_context()); std::string log_message; IPC::LogParam(output, &log_message); - EXPECT_STREQ("<GPUInfo> 10de 429 6.14.11.7715", log_message.c_str()); + EXPECT_STREQ("<GPUInfo> 10de 429 6.14.11.7715 1", log_message.c_str()); } diff --git a/chrome/common/gpu_param_traits.h b/chrome/common/gpu_param_traits.h new file mode 100644 index 0000000..d8ca851 --- /dev/null +++ b/chrome/common/gpu_param_traits.h @@ -0,0 +1,63 @@ +// 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. + +#ifndef CHROME_COMMON_GPU_PARAM_TRAITS_H_ +#define CHROME_COMMON_GPU_PARAM_TRAITS_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/process.h" +#include "chrome/common/common_param_traits.h" +#include "chrome/common/gpu_info.h" +#include "chrome/common/gpu_native_window_handle.h" +#include "gfx/native_widget_types.h" +#include "gfx/rect.h" +#include "gfx/size.h" +#include "gpu/command_buffer/common/command_buffer.h" + +#if defined(OS_MACOSX) +// Parameters for the GpuHostMsg_AcceleratedSurfaceSetIOSurface +// message, which has too many parameters to be sent with the +// predefined IPC macros. +struct GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params { + int32 renderer_id; + int32 render_view_id; + gfx::PluginWindowHandle window; + int32 width; + int32 height; + uint64 identifier; + + GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params(); +}; +#endif + +namespace IPC { +#if defined(OS_MACOSX) +template <> +struct ParamTraits<GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params> { + typedef GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params 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); +}; +#endif + +template <> +struct ParamTraits<GPUInfo> { + typedef GPUInfo 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); + static bool Read(const Message* m, void** iter, param_type* p); + static void Log(const param_type& p, std::string* l); +}; +} // namespace IPC + +#endif // CHROME_COMMON_GPU_PARAM_TRAITS_H_ diff --git a/chrome/common/render_messages.cc b/chrome/common/render_messages.cc index df94855..88bba47 100644 --- a/chrome/common/render_messages.cc +++ b/chrome/common/render_messages.cc @@ -8,6 +8,7 @@ #include "chrome/common/edit_command.h" #include "chrome/common/extensions/extension_extent.h" #include "chrome/common/extensions/url_pattern.h" +#include "chrome/common/gpu_param_traits.h" #include "chrome/common/indexed_db_param_traits.h" #include "chrome/common/render_messages_params.h" #include "chrome/common/thumbnail_score.h" diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 4a680e8..0abd39d 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -41,6 +41,7 @@ // Substitution map for l10n messages. typedef std::map<std::string, std::string> SubstitutionMap; +class GPUInfo; class SerializedScriptValue; class SkBitmap; struct ThumbnailScore; @@ -606,8 +607,9 @@ IPC_BEGIN_MESSAGES(View) // The browser sends this to a renderer process in response to a // ViewHostMsg_EstablishGpuChannel message. - IPC_MESSAGE_CONTROL1(ViewMsg_GpuChannelEstablished, - IPC::ChannelHandle /* handle to channel */) + IPC_MESSAGE_CONTROL2(ViewMsg_GpuChannelEstablished, + IPC::ChannelHandle /* handle to channel */, + GPUInfo /* stats about GPU process*/) // Notifies the renderer of the appcache that has been selected for a // a particular host. This is sent in reply to AppCacheMsg_SelectCache. diff --git a/chrome/gpu/DEPS b/chrome/gpu/DEPS index 9597b6b..cf48ed0 100644 --- a/chrome/gpu/DEPS +++ b/chrome/gpu/DEPS @@ -1,6 +1,8 @@ include_rules = [
"+chrome/app",
"+gpu/command_buffer",
+ "+libEGL",
+ "+libGLESv2",
"+media/base",
"+media/video",
]
diff --git a/chrome/gpu/gpu_info_collector.h b/chrome/gpu/gpu_info_collector.h index 0f9ce46..2b647c9 100644 --- a/chrome/gpu/gpu_info_collector.h +++ b/chrome/gpu/gpu_info_collector.h @@ -15,7 +15,7 @@ namespace gpu_info_collector { // Populate variables with necessary graphics card information. // Returns true on success. -bool CollectGraphicsInfo(GPUInfo& gpu_info); +bool CollectGraphicsInfo(GPUInfo* gpu_info); #if defined(OS_WIN) // Windows provides two ways of doing graphics so we need two ways of @@ -23,10 +23,10 @@ bool CollectGraphicsInfo(GPUInfo& gpu_info); // The selection between the two methods is done in the cc file. // A D3D argument is passed in for testing purposes -bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo& gpu_info); +bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info); // The GL version of collecting information -bool CollectGraphicsInfoGL(GPUInfo& gpu_info); +bool CollectGraphicsInfoGL(GPUInfo* gpu_info); #endif } // namespace gpu_info_collector diff --git a/chrome/gpu/gpu_info_collector_linux.cc b/chrome/gpu/gpu_info_collector_linux.cc index d6e08b4..2a4db9a 100644 --- a/chrome/gpu/gpu_info_collector_linux.cc +++ b/chrome/gpu/gpu_info_collector_linux.cc @@ -6,8 +6,12 @@ namespace gpu_info_collector { -bool CollectGraphicsInfo(GPUInfo& gpu_info) { +bool CollectGraphicsInfo(GPUInfo* gpu_info) { // TODO(rlp): complete this function + // TODO(apatrick): this illustrates how can_lose_context will be implemented + // on this platform in the future. + // bool can_lose_context = + // gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2; return true; } diff --git a/chrome/gpu/gpu_info_collector_mac.mm b/chrome/gpu/gpu_info_collector_mac.mm index b66098a..b5212d7 100644 --- a/chrome/gpu/gpu_info_collector_mac.mm +++ b/chrome/gpu/gpu_info_collector_mac.mm @@ -3,6 +3,8 @@ // found in the LICENSE file. #include "chrome/gpu/gpu_info_collector.h" +#include "base/logging.h" +#include "base/scoped_ptr.h" #include "base/string_piece.h" #include "base/sys_string_conversions.h" #include "app/gfx/gl/gl_context.h" @@ -125,7 +127,7 @@ static std::wstring CollectGLInfo(int *out_gl_version, } -bool CollectGraphicsInfo(GPUInfo& gpu_info) { +bool CollectGraphicsInfo(GPUInfo* gpu_info) { // Video Card data. int vendor_id = 0, device_id = 0; // OpenGL data. @@ -136,8 +138,9 @@ bool CollectGraphicsInfo(GPUInfo& gpu_info) { // Temporarily make an offscreen GL context so we can gather info from it. if (gfx::GLContext::InitializeOneOff()) { - gfx::GLContext* ctx = gfx::GLContext::CreateOffscreenGLContext(NULL); - if (ctx) { + scoped_ptr<gfx::GLContext> ctx( + gfx::GLContext::CreateOffscreenGLContext(NULL)); + if (ctx.get()) { if (ctx->MakeCurrent()) { driver_version = CollectGLInfo(&gl_version, &shader_version); } @@ -148,10 +151,13 @@ bool CollectGraphicsInfo(GPUInfo& gpu_info) { // OpenGL doesn't have separate versions for pixel and vertex shader // languages, so we just pass the shader_version for both. - gpu_info.SetGraphicsInfo(vendor_id, device_id, - driver_version, - shader_version, shader_version, - gl_version); + gpu_info->SetGraphicsInfo(vendor_id, + device_id, + driver_version, + shader_version, + shader_version, + gl_version, + false); return true; } diff --git a/chrome/gpu/gpu_info_collector_win.cc b/chrome/gpu/gpu_info_collector_win.cc index 7b4101e..1ce5792 100644 --- a/chrome/gpu/gpu_info_collector_win.cc +++ b/chrome/gpu/gpu_info_collector_win.cc @@ -7,34 +7,38 @@ #include <windows.h> #include <d3d9.h> +#include "app/gfx/gl/gl_context_egl.h" +#include "app/gfx/gl/gl_implementation.h" #include "base/file_path.h" #include "base/logging.h" #include "base/scoped_native_library.h" #include "base/string_util.h" -namespace gpu_info_collector { +// ANGLE seems to require that main.h be included before any other ANGLE header. +#include "libEGL/main.h" +#include "libEGL/Display.h" -bool CollectGraphicsInfo(GPUInfo& gpu_info) { - FilePath d3d_path(base::GetNativeLibraryName(L"d3d9")); - base::ScopedNativeLibrary d3dlib(d3d_path); +namespace gpu_info_collector { - typedef IDirect3D9* (WINAPI *Direct3DCreate9Proc)(UINT); - Direct3DCreate9Proc d3d_create_proc = - static_cast<Direct3DCreate9Proc>( - d3dlib.GetFunctionPointer("Direct3DCreate9")); +bool CollectGraphicsInfo(GPUInfo* gpu_info) { + // TODO: collect OpenGL info if not using ANGLE? + if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) + return true; - if (!d3d_create_proc) { + egl::Display* display = static_cast<egl::Display*>( + gfx::BaseEGLContext::GetDisplay()); + IDirect3DDevice9* device = display->getDevice(); + IDirect3D9* d3d = NULL; + if (FAILED(device->GetDirect3D(&d3d))) return false; - } - IDirect3D9 *d3d = d3d_create_proc(D3D_SDK_VERSION); - if (!d3d) { - return false; - } + return CollectGraphicsInfoD3D(d3d, gpu_info); } -bool CollectGraphicsInfoD3D(IDirect3D9* d3d, - GPUInfo& gpu_info) { +bool CollectGraphicsInfoD3D(IDirect3D9* d3d, GPUInfo* gpu_info) { + DCHECK(d3d); + DCHECK(gpu_info); + // Get device information D3DADAPTER_IDENTIFIER9 identifier; HRESULT hr = d3d->GetAdapterIdentifier(D3DADAPTER_DEFAULT, 0, &identifier); @@ -63,18 +67,33 @@ bool CollectGraphicsInfoD3D(IDirect3D9* d3d, driver_major_version_lo, driver_minor_version_hi, driver_minor_version_lo); + + bool can_lose_context = false; + IDirect3D9Ex* d3dex = NULL; + if (SUCCEEDED(d3d->QueryInterface(__uuidof(IDirect3D9Ex), + reinterpret_cast<void**>(&d3dex)))) { + d3dex->Release(); + } else { + can_lose_context = true; + } + d3d->Release(); // Get shader versions uint32 pixel_shader_version = d3d_caps.PixelShaderVersion; uint32 vertex_shader_version = d3d_caps.VertexShaderVersion; - gpu_info.SetGraphicsInfo(vendor_id, device_id, driver_version, - pixel_shader_version, vertex_shader_version, 0); + gpu_info->SetGraphicsInfo(vendor_id, + device_id, + driver_version, + pixel_shader_version, + vertex_shader_version, + 0, + can_lose_context); return true; } -bool CollectGraphicsInfoGL(GPUInfo& gpu_info) { +bool CollectGraphicsInfoGL(GPUInfo* gpu_info) { // Taken from http://developer.nvidia.com/object/device_ids.html DISPLAY_DEVICE dd; dd.cb = sizeof(DISPLAY_DEVICE); @@ -99,8 +118,11 @@ bool CollectGraphicsInfoGL(GPUInfo& gpu_info) { std::wstring driver_version = L""; uint32 pixel_shader_version = 0; uint32 vertex_shader_version = 0; - gpu_info.SetGraphicsInfo(vendor_id, device_id, driver_version, - pixel_shader_version, vertex_shader_version, 0); + gpu_info->SetGraphicsInfo(vendor_id, device_id, driver_version, + pixel_shader_version, + vertex_shader_version, + 0, // GL version of 0 indicates D3D + false); return true; // TODO(rlp): Add driver and pixel versions diff --git a/chrome/gpu/gpu_info_unittest_win.cc b/chrome/gpu/gpu_info_unittest_win.cc index 45a064d..5cf7af9 100644 --- a/chrome/gpu/gpu_info_unittest_win.cc +++ b/chrome/gpu/gpu_info_unittest_win.cc @@ -31,10 +31,12 @@ class GPUInfoTest : public testing::Test { EXPECT_CALL(d3d_, GetAdapterIdentifier(_, _, _)) .WillOnce(DoAll(SetArgumentPointee<2>(test_identifier_), Return(D3D_OK))); - EXPECT_CALL(d3d_, Release()); EXPECT_CALL(d3d_, GetDeviceCaps(_, _, _)) .WillOnce(DoAll(SetArgumentPointee<2>(test_caps_), Return(D3D_OK))); + EXPECT_CALL(d3d_, QueryInterface(__uuidof(IDirect3D9Ex), _)) + .WillOnce(Return(E_NOINTERFACE)); + EXPECT_CALL(d3d_, Release()); } void TearDown() { } @@ -48,19 +50,19 @@ class GPUInfoTest : public testing::Test { TEST_F(GPUInfoTest, VendorIdD3D) { GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, gpu_info)); + ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); EXPECT_EQ(gpu_info.vendor_id(), 0x10de); } TEST_F(GPUInfoTest, DeviceIdD3D) { GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, gpu_info)); + ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); EXPECT_EQ(gpu_info.device_id(), 0x429); } TEST_F(GPUInfoTest, DriverVersionD3D) { GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, gpu_info)); + ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); std::wstring driver_version = gpu_info.driver_version(); EXPECT_FALSE(driver_version.empty()); EXPECT_EQ(driver_version, L"6.14.11.7715"); @@ -68,14 +70,14 @@ TEST_F(GPUInfoTest, DriverVersionD3D) { TEST_F(GPUInfoTest, PixelShaderVersionD3D) { GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, gpu_info)); + ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); uint32 ps_version = gpu_info.pixel_shader_version(); EXPECT_EQ(ps_version, D3DPS_VERSION(3, 0)); } TEST_F(GPUInfoTest, VertexShaderVersionD3D) { GPUInfo gpu_info; - ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, gpu_info)); + ASSERT_TRUE(gpu_info_collector::CollectGraphicsInfoD3D(&d3d_, &gpu_info)); uint32 vs_version = gpu_info.vertex_shader_version(); EXPECT_EQ(vs_version, D3DVS_VERSION(3, 0)); } diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc index 04bd218..2ce492c 100644 --- a/chrome/gpu/gpu_thread.cc +++ b/chrome/gpu/gpu_thread.cc @@ -92,39 +92,40 @@ void GpuThread::OnControlMessageReceived(const IPC::Message& msg) { void GpuThread::OnEstablishChannel(int renderer_id) { scoped_refptr<GpuChannel> channel; IPC::ChannelHandle channel_handle; + GPUInfo gpu_info; // Fail to establish a channel if some implementation of GL cannot be // initialized. if (gfx::GLContext::InitializeOneOff()) { - GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id); - if (iter == gpu_channels_.end()) { - channel = new GpuChannel(renderer_id); - } else { - channel = iter->second; - } - - DCHECK(channel != NULL); - - if (channel->Init()) { - gpu_channels_[renderer_id] = channel; - } else { - channel = NULL; - } - - if (channel.get()) { - channel_handle.name = channel->GetChannelName(); + // Fail to establish channel if GPU stats cannot be retreived. + if (gpu_info_collector::CollectGraphicsInfo(&gpu_info)) { + GpuChannelMap::const_iterator iter = gpu_channels_.find(renderer_id); + if (iter == gpu_channels_.end()) { + channel = new GpuChannel(renderer_id); + } else { + channel = iter->second; + } + + DCHECK(channel != NULL); + + if (channel->Init()) { + gpu_channels_[renderer_id] = channel; + } else { + channel = NULL; + } + + if (channel.get()) { + channel_handle.name = channel->GetChannelName(); #if defined(OS_POSIX) - // On POSIX, pass the renderer-side FD. Also mark it as auto-close so that - // it gets closed after it has been sent. - int renderer_fd = channel->DisownRendererFd(); - channel_handle.socket = base::FileDescriptor(renderer_fd, true); + // On POSIX, pass the renderer-side FD. Also mark it as auto-close so + // that it gets closed after it has been sent. + int renderer_fd = channel->DisownRendererFd(); + channel_handle.socket = base::FileDescriptor(renderer_fd, true); #endif + } } } - GPUInfo gpu_info; - gpu_info_collector::CollectGraphicsInfo(gpu_info); - Send(new GpuHostMsg_ChannelEstablished(channel_handle, gpu_info)); } diff --git a/chrome/renderer/gpu_channel_host.cc b/chrome/renderer/gpu_channel_host.cc index bb98148..b4e5bd1 100644 --- a/chrome/renderer/gpu_channel_host.cc +++ b/chrome/renderer/gpu_channel_host.cc @@ -28,6 +28,14 @@ void GpuChannelHost::Connect(const std::string& channel_name) { state_ = CONNECTED; } +void GpuChannelHost::set_gpu_info(const GPUInfo& gpu_info) { + gpu_info_ = gpu_info; +} + +const GPUInfo& GpuChannelHost::gpu_info() const { + return gpu_info_; +} + void GpuChannelHost::OnMessageReceived(const IPC::Message& message) { DCHECK(message.routing_id() != MSG_ROUTING_CONTROL); if (!router_.RouteMessage(message)) { diff --git a/chrome/renderer/gpu_channel_host.h b/chrome/renderer/gpu_channel_host.h index e35d40d..4df29a4 100644 --- a/chrome/renderer/gpu_channel_host.h +++ b/chrome/renderer/gpu_channel_host.h @@ -10,6 +10,7 @@ #include "base/hash_tables.h" #include "base/scoped_ptr.h" +#include "chrome/common/gpu_info.h" #include "chrome/common/message_router.h" #include "gfx/native_widget_types.h" #include "gfx/size.h" @@ -44,6 +45,10 @@ class GpuChannelHost : public IPC::Channel::Listener, State state() const { return state_; } + // The GPU stats reported by the GPU process. + void set_gpu_info(const GPUInfo& gpu_info); + const GPUInfo& gpu_info() const; + // IPC::Channel::Listener implementation: virtual void OnMessageReceived(const IPC::Message& msg); virtual void OnChannelConnected(int32 peer_pid); @@ -67,6 +72,8 @@ class GpuChannelHost : public IPC::Channel::Listener, private: State state_; + GPUInfo gpu_info_; + scoped_ptr<IPC::SyncChannel> channel_; // Used to implement message routing functionality to CommandBufferProxy diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index 851d931..9aad4dc 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -1081,13 +1081,15 @@ void RenderThread::OnSetIsIncognitoProcess(bool is_incognito_process) { } void RenderThread::OnGpuChannelEstablished( - const IPC::ChannelHandle& channel_handle) { + const IPC::ChannelHandle& channel_handle, const GPUInfo& gpu_info) { #if defined(OS_POSIX) // If we received a ChannelHandle, register it now. if (channel_handle.socket.fd >= 0) IPC::AddChannelSocket(channel_handle.name, channel_handle.socket.fd); #endif + gpu_channel_->set_gpu_info(gpu_info); + if (channel_handle.name.size() != 0) { // Connect to the GPU process if a channel name was received. gpu_channel_->Connect(channel_handle.name); diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 8795fb7..76d9428 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -15,6 +15,7 @@ #include "build/build_config.h" #include "chrome/common/child_thread.h" #include "chrome/common/css_colors.h" +#include "chrome/common/gpu_info.h" #include "chrome/renderer/visitedlink_slave.h" #include "gfx/native_widget_types.h" #include "ipc/ipc_channel_proxy.h" @@ -289,7 +290,8 @@ class RenderThread : public RenderThreadBase, void OnSpellCheckWordAdded(const std::string& word); void OnSpellCheckEnableAutoSpellCorrect(bool enable); - void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle); + void OnGpuChannelEstablished(const IPC::ChannelHandle& channel_handle, + const GPUInfo& gpu_info); void OnGetAccessibilityTree(); |