diff options
Diffstat (limited to 'chrome/gpu')
-rw-r--r-- | chrome/gpu/gpu_channel.cc | 112 | ||||
-rw-r--r-- | chrome/gpu/gpu_channel.h | 32 | ||||
-rw-r--r-- | chrome/gpu/gpu_command_buffer_stub.cc | 34 | ||||
-rw-r--r-- | chrome/gpu/gpu_command_buffer_stub.h | 16 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.cc | 24 | ||||
-rw-r--r-- | chrome/gpu/gpu_thread.h | 4 |
6 files changed, 153 insertions, 69 deletions
diff --git a/chrome/gpu/gpu_channel.cc b/chrome/gpu/gpu_channel.cc index 4269022..b2b5bf9 100644 --- a/chrome/gpu/gpu_channel.cc +++ b/chrome/gpu/gpu_channel.cc @@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#if defined(OS_WIN) +#include <windows.h> +#endif + #include "chrome/gpu/gpu_channel.h" #include "base/command_line.h" @@ -11,6 +15,7 @@ #include "base/waitable_event.h" #include "build/build_config.h" #include "chrome/common/child_process.h" +#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_thread.h" @@ -27,44 +32,12 @@ class GpuReleaseTask : public Task { } }; -typedef base::hash_map<std::string, scoped_refptr<GpuChannel> > - GpuChannelMap; - // How long we wait before releasing the GPU process. const int kGpuReleaseTimeMS = 10000; - -GpuChannelMap g_gpu_channels; } // namespace anonymous -GpuChannel* GpuChannel::EstablishGpuChannel(int renderer_id) { - // Map renderer ID to a (single) channel to that process. - std::string channel_name = StringPrintf( - "%d.r%d", base::GetCurrentProcId(), renderer_id); - - scoped_refptr<GpuChannel> channel; - - GpuChannelMap::const_iterator iter = g_gpu_channels.find(channel_name); - if (iter == g_gpu_channels.end()) { - channel = new GpuChannel; - } else { - channel = iter->second; - } - - DCHECK(channel != NULL); - - if (!channel->channel_.get()) { - if (channel->Init(channel_name)) { - g_gpu_channels[channel_name] = channel; - } else { - channel = NULL; - } - } - - return channel.get(); -} - -GpuChannel::GpuChannel() - : renderer_id_(-1) +GpuChannel::GpuChannel(int renderer_id) + : renderer_id_(renderer_id) #if defined(OS_POSIX) , renderer_fd_(-1) #endif @@ -141,8 +114,10 @@ bool GpuChannel::Send(IPC::Message* message) { void GpuChannel::OnControlMessageReceived(const IPC::Message& msg) { IPC_BEGIN_MESSAGE_MAP(GpuChannel, msg) - IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateCommandBuffer, - OnCreateCommandBuffer) + IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateViewCommandBuffer, + OnCreateViewCommandBuffer) + IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateOffscreenCommandBuffer, + OnCreateOffscreenCommandBuffer) IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer, OnDestroyCommandBuffer) IPC_MESSAGE_UNHANDLED_ERROR() @@ -154,11 +129,57 @@ int GpuChannel::GenerateRouteID() { return ++last_id; } -void GpuChannel::OnCreateCommandBuffer(int* route_id) { +void GpuChannel::OnCreateViewCommandBuffer(gfx::NativeViewId view_id, + int32* route_id) { + *route_id = 0; + #if defined(ENABLE_GPU) + +#if defined(OS_WIN) + gfx::NativeView view = gfx::NativeViewFromId(view_id); + + // Check that the calling renderer is allowed to render to this window. + // TODO(apatrick): consider killing the renderer process rather than failing. + int view_renderer_id = reinterpret_cast<int>( + GetProp(view, chrome::kChromiumRendererIdProperty)); + if (view_renderer_id != renderer_id_) + return; +#else + // TODO(apatrick): This needs to be something valid for mac and linux. + // Offscreen rendering will work on these platforms but not rendering to the + // window. + DCHECK_EQ(view_id, 0); + gfx::NativeView view = 0; +#endif + *route_id = GenerateRouteID(); scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( - this, *route_id); + this, view, NULL, gfx::Size(), 0, *route_id); + router_.AddRoute(*route_id, stub); + stubs_[*route_id] = stub; +#endif // ENABLE_GPU +} + +void GpuChannel::OnCreateOffscreenCommandBuffer(int32 parent_route_id, + const gfx::Size& size, + uint32 parent_texture_id, + int32* route_id) { +#if defined(ENABLE_GPU) + *route_id = GenerateRouteID(); + scoped_refptr<GpuCommandBufferStub> parent_stub; + if (parent_route_id != 0) { + StubMap::iterator it = stubs_.find(parent_route_id); + DCHECK(it != stubs_.end()); + parent_stub = it->second; + } + + scoped_refptr<GpuCommandBufferStub> stub = new GpuCommandBufferStub( + this, + NULL, + parent_stub.get(), + size, + parent_texture_id, + *route_id); router_.AddRoute(*route_id, stub); stubs_[*route_id] = stub; #else @@ -166,7 +187,7 @@ void GpuChannel::OnCreateCommandBuffer(int* route_id) { #endif } -void GpuChannel::OnDestroyCommandBuffer(int route_id) { +void GpuChannel::OnDestroyCommandBuffer(int32 route_id) { #if defined(ENABLE_GPU) StubMap::iterator it = stubs_.find(route_id); DCHECK(it != stubs_.end()); @@ -175,8 +196,13 @@ void GpuChannel::OnDestroyCommandBuffer(int route_id) { #endif } -bool GpuChannel::Init(const std::string& channel_name) { - channel_name_ = channel_name; +bool GpuChannel::Init() { + // Check whether we're already initialized. + if (channel_.get()) + return true; + + // Map renderer ID to a (single) channel to that process. + std::string channel_name = GetChannelName(); #if defined(OS_POSIX) // This gets called when the GpuChannel is initially created. At this // point, create the socketpair and assign the GPU side FD to the channel @@ -192,3 +218,7 @@ bool GpuChannel::Init(const std::string& channel_name) { ChildProcess::current()->GetShutDownEvent())); return true; } + +std::string GpuChannel::GetChannelName() { + return StringPrintf("%d.r%d", base::GetCurrentProcId(), renderer_id_); +} diff --git a/chrome/gpu/gpu_channel.h b/chrome/gpu/gpu_channel.h index 17ea363..60dc906 100644 --- a/chrome/gpu/gpu_channel.h +++ b/chrome/gpu/gpu_channel.h @@ -13,6 +13,8 @@ #include "build/build_config.h" #include "chrome/common/message_router.h" #include "chrome/gpu/gpu_command_buffer_stub.h" +#include "gfx/native_widget_types.h" +#include "gfx/size.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sync_channel.h" @@ -23,17 +25,12 @@ class GpuChannel : public IPC::Channel::Listener, public IPC::Message::Sender, public base::RefCountedThreadSafe<GpuChannel> { public: - // Get a new GpuChannel object for the current process to talk to the - // given renderer process. The renderer ID is an opaque unique ID generated - // by the browser. - // - // POSIX only: If |channel_fd| > 0, use that file descriptor for the - // channel socket. - static GpuChannel* EstablishGpuChannel(int renderer_id); - + explicit GpuChannel(int renderer_id); virtual ~GpuChannel(); - std::string channel_name() const { return channel_name_; } + bool Init(); + + std::string GetChannelName(); base::ProcessHandle renderer_handle() const { return renderer_process_.handle(); @@ -60,21 +57,20 @@ class GpuChannel : public IPC::Channel::Listener, virtual bool Send(IPC::Message* msg); private: - // Called on the plugin thread - GpuChannel(); - - bool Init(const std::string& channel_name); - void OnControlMessageReceived(const IPC::Message& msg); int GenerateRouteID(); // Message handlers. - void OnCreateCommandBuffer(int* instance_id); - void OnDestroyCommandBuffer(int instance_id); + void OnCreateViewCommandBuffer(gfx::NativeViewId view, + int32* route_id); + void OnCreateOffscreenCommandBuffer(int32 parent_route_id, + const gfx::Size& size, + uint32 parent_texture_id, + int32* route_id); + void OnDestroyCommandBuffer(int32 route_id); scoped_ptr<IPC::SyncChannel> channel_; - std::string channel_name_; // Handle to the renderer process who is on the other side of the channel. base::ScopedOpenProcess renderer_process_; @@ -92,7 +88,7 @@ class GpuChannel : public IPC::Channel::Listener, MessageRouter router_; #if defined(ENABLE_GPU) - typedef base::hash_map<int, scoped_refptr<GpuCommandBufferStub> > StubMap; + typedef base::hash_map<int32, scoped_refptr<GpuCommandBufferStub> > StubMap; StubMap stubs_; #endif diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc index 6c3f5cc..5d6842d 100644 --- a/chrome/gpu/gpu_command_buffer_stub.cc +++ b/chrome/gpu/gpu_command_buffer_stub.cc @@ -6,6 +6,7 @@ #include "base/process_util.h" #include "base/shared_memory.h" +#include "build/build_config.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_command_buffer_stub.h" @@ -13,12 +14,23 @@ using gpu::Buffer; GpuCommandBufferStub::GpuCommandBufferStub(GpuChannel* channel, + gfx::NativeView view, + GpuCommandBufferStub* parent, + const gfx::Size& size, + uint32 parent_texture_id, int32 route_id) : channel_(channel), + view_(view), + parent_(parent), + initial_size_(size), + parent_texture_id_(parent_texture_id), route_id_(route_id) { } GpuCommandBufferStub::~GpuCommandBufferStub() { + if (processor_.get()) { + processor_->Destroy(); + } } void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { @@ -34,6 +46,8 @@ void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { OnDestroyTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer, OnGetTransferBuffer); + IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer, + OnResizeOffscreenFrameBuffer); IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() } @@ -55,8 +69,18 @@ void GpuCommandBufferStub::OnInitialize( if (command_buffer_->Initialize(size)) { Buffer buffer = command_buffer_->GetRingBuffer(); if (buffer.shared_memory) { - processor_ = new gpu::GPUProcessor(command_buffer_.get()); - if (processor_->Initialize(gfx::kNullPluginWindow)) { + gpu::GPUProcessor* parent_processor = + parent_ ? parent_->processor_.get() : NULL; + processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); + // TODO(apatrick): The reinterpret_cast below is only valid on windows. +#if !defined(OS_WIN) + DCHECK_EQ(view_, static_cast<gfx::NativeView>(0)); +#endif + if (processor_->Initialize( + reinterpret_cast<gfx::PluginWindowHandle>(view_), + parent_processor, + initial_size_, + parent_texture_id_)) { command_buffer_->SetPutOffsetChangeCallback( NewCallback(processor_.get(), &gpu::GPUProcessor::ProcessCommands)); @@ -66,7 +90,7 @@ void GpuCommandBufferStub::OnInitialize( buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), ring_buffer); } else { - processor_ = NULL; + processor_.reset(); command_buffer_.reset(); } } @@ -117,4 +141,8 @@ void GpuCommandBufferStub::OnGetTransferBuffer( } } +void GpuCommandBufferStub::OnResizeOffscreenFrameBuffer(const gfx::Size& size) { + processor_->ResizeOffscreenFrameBuffer(size); +} + #endif // ENABLE_GPU diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h index eb927a3..7aaf68a 100644 --- a/chrome/gpu/gpu_command_buffer_stub.h +++ b/chrome/gpu/gpu_command_buffer_stub.h @@ -10,6 +10,7 @@ #include "base/process.h" #include "base/ref_counted.h" #include "gfx/native_widget_types.h" +#include "gfx/size.h" #include "gpu/command_buffer/service/command_buffer_service.h" #include "gpu/command_buffer/service/gpu_processor.h" #include "ipc/ipc_channel.h" @@ -23,6 +24,10 @@ class GpuCommandBufferStub public base::RefCountedThreadSafe<GpuCommandBufferStub> { public: GpuCommandBufferStub(GpuChannel* channel, + gfx::NativeView view, + GpuCommandBufferStub* parent, + const gfx::Size& size, + uint32 parent_texture_id, int32 route_id); virtual ~GpuCommandBufferStub(); @@ -33,7 +38,7 @@ class GpuCommandBufferStub // IPC::Message::Sender implementation: virtual bool Send(IPC::Message* msg); - int route_id() const { return route_id_; } + int32 route_id() const { return route_id_; } private: // Message handlers: @@ -47,12 +52,17 @@ class GpuCommandBufferStub void OnGetTransferBuffer(int32 id, base::SharedMemoryHandle* transfer_buffer, uint32* size); + void OnResizeOffscreenFrameBuffer(const gfx::Size& size); scoped_refptr<GpuChannel> channel_; - int route_id_; + gfx::NativeView view_; + scoped_refptr<GpuCommandBufferStub> parent_; + gfx::Size initial_size_; + uint32 parent_texture_id_; + int32 route_id_; scoped_ptr<gpu::CommandBufferService> command_buffer_; - scoped_refptr<gpu::GPUProcessor> processor_; + scoped_ptr<gpu::GPUProcessor> processor_; DISALLOW_COPY_AND_ASSIGN(GpuCommandBufferStub); }; diff --git a/chrome/gpu/gpu_thread.cc b/chrome/gpu/gpu_thread.cc index 1839412..9de441c 100644 --- a/chrome/gpu/gpu_thread.cc +++ b/chrome/gpu/gpu_thread.cc @@ -7,7 +7,6 @@ #include "build/build_config.h" #include "chrome/common/child_process.h" #include "chrome/common/gpu_messages.h" -#include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_config.h" #if defined(OS_WIN) @@ -47,11 +46,28 @@ void GpuThread::OnControlMessageReceived(const IPC::Message& msg) { } void GpuThread::OnEstablishChannel(int renderer_id) { - scoped_refptr<GpuChannel> channel = - GpuChannel::EstablishGpuChannel(renderer_id); + scoped_refptr<GpuChannel> channel; + + 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()) { + // TODO(apatrick): figure out when to remove channels from the map. They + // will never be destroyed otherwise. + gpu_channels_[renderer_id] = channel; + } else { + channel = NULL; + } + IPC::ChannelHandle channel_handle; if (channel.get()) { - channel_handle.name = channel->channel_name(); + 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. diff --git a/chrome/gpu/gpu_thread.h b/chrome/gpu/gpu_thread.h index c32b513..23b8ba1 100644 --- a/chrome/gpu/gpu_thread.h +++ b/chrome/gpu/gpu_thread.h @@ -10,6 +10,7 @@ #include "build/build_config.h" #include "chrome/common/child_thread.h" #include "chrome/common/gpu_native_window_handle.h" +#include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_config.h" #include "chrome/gpu/x_util.h" #include "gfx/native_widget_types.h" @@ -38,6 +39,9 @@ class GpuThread : public ChildThread { void OnNewRenderWidgetHostView(GpuNativeWindowHandle parent_window, int32 routing_id); + typedef base::hash_map<int, scoped_refptr<GpuChannel> > GpuChannelMap; + GpuChannelMap gpu_channels_; + #if defined(GPU_USE_GLX) Display* display_; scoped_ptr<GpuBackingStoreGLXContext> glx_context_; |