summaryrefslogtreecommitdiffstats
path: root/chrome/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/gpu')
-rw-r--r--chrome/gpu/gpu_channel.cc112
-rw-r--r--chrome/gpu/gpu_channel.h32
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.cc34
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.h16
-rw-r--r--chrome/gpu/gpu_thread.cc24
-rw-r--r--chrome/gpu/gpu_thread.h4
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_;