diff options
author | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 23:36:54 +0000 |
---|---|---|
committer | apatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 23:36:54 +0000 |
commit | 36dbfe198cb0eab50ff4a7300fc86b8314d30cde (patch) | |
tree | c7b2271be2e885ca87ac58d53e338cca322276a4 /chrome | |
parent | 406e6e22b82ef80e8bc44f45d85efa68799bc552 (diff) | |
download | chromium_src-36dbfe198cb0eab50ff4a7300fc86b8314d30cde.zip chromium_src-36dbfe198cb0eab50ff4a7300fc86b8314d30cde.tar.gz chromium_src-36dbfe198cb0eab50ff4a7300fc86b8314d30cde.tar.bz2 |
Moved creation of GPU command buffer shared memory into the browser process.
This is to allow the GPU process to be sandboxed on all platforms.
TEST=try, run WebGL app on win and mac.
BUG=none
Review URL: http://codereview.chromium.org/6588029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76307 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/common/gpu_messages_internal.h | 5 | ||||
-rw-r--r-- | chrome/gpu/gpu_command_buffer_stub.cc | 90 | ||||
-rw-r--r-- | chrome/gpu/gpu_command_buffer_stub.h | 4 | ||||
-rw-r--r-- | chrome/plugin/command_buffer_stub.cc | 70 | ||||
-rw-r--r-- | chrome/plugin/command_buffer_stub.h | 4 | ||||
-rw-r--r-- | chrome/renderer/command_buffer_proxy.cc | 62 | ||||
-rw-r--r-- | chrome/renderer/command_buffer_proxy.h | 1 |
7 files changed, 119 insertions, 117 deletions
diff --git a/chrome/common/gpu_messages_internal.h b/chrome/common/gpu_messages_internal.h index b95a42a..eaf5088 100644 --- a/chrome/common/gpu_messages_internal.h +++ b/chrome/common/gpu_messages_internal.h @@ -225,9 +225,10 @@ IPC_SYNC_MESSAGE_CONTROL1_0(GpuChannelMsg_DestroyVideoDecoder, // Initialize a command buffer with the given number of command entries. // Returns the shared memory handle for the command buffer mapped to the // calling process. -IPC_SYNC_MESSAGE_ROUTED1_1(GpuCommandBufferMsg_Initialize, +IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_Initialize, + base::SharedMemoryHandle /* ring_buffer */, int32 /* size */, - base::SharedMemoryHandle /* ring_buffer */) + bool /* result */) // Get the current state of the command buffer. IPC_SYNC_MESSAGE_ROUTED0_1(GpuCommandBufferMsg_GetState, diff --git a/chrome/gpu/gpu_command_buffer_stub.cc b/chrome/gpu/gpu_command_buffer_stub.cc index 5b81d22..0bf5427 100644 --- a/chrome/gpu/gpu_command_buffer_stub.cc +++ b/chrome/gpu/gpu_command_buffer_stub.cc @@ -192,11 +192,12 @@ bool GpuCommandBufferStub::Send(IPC::Message* message) { } void GpuCommandBufferStub::OnInitialize( + base::SharedMemoryHandle ring_buffer, int32 size, - base::SharedMemoryHandle* ring_buffer) { + bool* result) { DCHECK(!command_buffer_.get()); - *ring_buffer = base::SharedMemory::NULLHandle(); + *result = false; command_buffer_.reset(new gpu::CommandBufferService); @@ -215,50 +216,57 @@ void GpuCommandBufferStub::OnInitialize( gfx::PluginWindowHandle output_window_handle = handle_; #endif // defined(OS_WIN) +#if defined(OS_WIN) + // Windows dups the shared memory handle it receives into the current process + // and closes it when this variable goes out of scope. + base::SharedMemory shared_memory(ring_buffer, + false, + channel_->renderer_process()); +#else + // POSIX receives a dup of the shared memory handle and closes the dup when + // this variable goes out of scope. + base::SharedMemory shared_memory(ring_buffer, false); +#endif + // Initialize the CommandBufferService and GPUProcessor. - if (command_buffer_->Initialize(size)) { - Buffer buffer = command_buffer_->GetRingBuffer(); - if (buffer.shared_memory) { - gpu::GPUProcessor* parent_processor = - parent_ ? parent_->processor_.get() : NULL; - processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); - if (processor_->Initialize( - output_window_handle, - initial_size_, - allowed_extensions_.c_str(), - requested_attribs_, - parent_processor, - parent_texture_id_)) { - command_buffer_->SetPutOffsetChangeCallback( - NewCallback(processor_.get(), - &gpu::GPUProcessor::ProcessCommands)); - processor_->SetSwapBuffersCallback( - NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); + if (command_buffer_->Initialize(&shared_memory, size)) { + gpu::GPUProcessor* parent_processor = + parent_ ? parent_->processor_.get() : NULL; + processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); + if (processor_->Initialize( + output_window_handle, + initial_size_, + allowed_extensions_.c_str(), + requested_attribs_, + parent_processor, + parent_texture_id_)) { + command_buffer_->SetPutOffsetChangeCallback( + NewCallback(processor_.get(), + &gpu::GPUProcessor::ProcessCommands)); + processor_->SetSwapBuffersCallback( + NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); - // Assume service is responsible for duplicating the handle from the - // calling process. - buffer.shared_memory->ShareToProcess(channel_->renderer_process(), - ring_buffer); #if defined(OS_MACOSX) - if (handle_) { - // This context conceptually puts its output directly on the - // screen, rendered by the accelerated plugin layer in - // RenderWidgetHostViewMac. Set up a pathway to notify the - // browser process when its contents change. - processor_->SetSwapBuffersCallback( - NewCallback(this, - &GpuCommandBufferStub::SwapBuffersCallback)); - } + if (handle_) { + // This context conceptually puts its output directly on the + // screen, rendered by the accelerated plugin layer in + // RenderWidgetHostViewMac. Set up a pathway to notify the + // browser process when its contents change. + processor_->SetSwapBuffersCallback( + NewCallback(this, + &GpuCommandBufferStub::SwapBuffersCallback)); + } #endif // defined(OS_MACOSX) - // Set up a pathway for resizing the output window or framebuffer at the - // right time relative to other GL commands. - processor_->SetResizeCallback( - NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); - } else { - processor_.reset(); - command_buffer_.reset(); - } + // Set up a pathway for resizing the output window or framebuffer at the + // right time relative to other GL commands. + processor_->SetResizeCallback( + NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); + + *result = true; + } else { + processor_.reset(); + command_buffer_.reset(); } } } diff --git a/chrome/gpu/gpu_command_buffer_stub.h b/chrome/gpu/gpu_command_buffer_stub.h index 2382410..7124e25 100644 --- a/chrome/gpu/gpu_command_buffer_stub.h +++ b/chrome/gpu/gpu_command_buffer_stub.h @@ -68,7 +68,9 @@ class GpuCommandBufferStub private: // Message handlers: - void OnInitialize(int32 size, base::SharedMemoryHandle* ring_buffer); + void OnInitialize(base::SharedMemoryHandle ring_buffer, + int32 size, + bool* result); void OnGetState(gpu::CommandBuffer::State* state); void OnAsyncGetState(); void OnFlush(int32 put_offset, gpu::CommandBuffer::State* state); diff --git a/chrome/plugin/command_buffer_stub.cc b/chrome/plugin/command_buffer_stub.cc index 2ef657a..9aea1ee 100644 --- a/chrome/plugin/command_buffer_stub.cc +++ b/chrome/plugin/command_buffer_stub.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/plugin/command_buffer_stub.h" + #include "base/callback.h" #include "base/scoped_open_process.h" #include "base/shared_memory.h" #include "chrome/common/gpu_messages.h" #include "chrome/common/plugin_messages.h" -#include "chrome/plugin/command_buffer_stub.h" #include "chrome/plugin/plugin_channel.h" using gpu::Buffer; @@ -67,66 +68,13 @@ void CommandBufferStub::NotifyRepaint() { Send(new GpuCommandBufferMsg_NotifyRepaint(route_id_)); } -void CommandBufferStub::OnInitialize(int32 size, - base::SharedMemoryHandle* ring_buffer) { - DCHECK(!command_buffer_.get()); - - *ring_buffer = base::SharedMemory::NULLHandle(); - - // Assume service is responsible for duplicating the handle from the calling - // process. - base::ScopedOpenProcess peer_process; - if (!peer_process.Open(channel_->peer_pid())) - return; - - command_buffer_.reset(new gpu::CommandBufferService); - - // Initialize the CommandBufferService. - if (!command_buffer_->Initialize(size)) { - Destroy(); - return; - } - - // Get the ring buffer. - Buffer buffer = command_buffer_->GetRingBuffer(); - if (!buffer.shared_memory) { - Destroy(); - return; - } - - // Initialize the GPUProcessor. - processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); - if (!processor_->Initialize(window_, gfx::Size(), NULL, std::vector<int32>(), - NULL, 0)) { - Destroy(); - return; - } - - // Perform platform specific initialization. - if (!InitializePlatformSpecific()) { - Destroy(); - return; - } - - // Share the ring buffer to the client process. - if (!buffer.shared_memory->ShareToProcess(peer_process.handle(), - ring_buffer)) { - Destroy(); - return; - } - - // Setup callbacks for events. - command_buffer_->SetPutOffsetChangeCallback( - NewCallback(processor_.get(), - &gpu::GPUProcessor::ProcessCommands)); -#if defined(OS_MACOSX) - processor_->SetSwapBuffersCallback( - NewCallback(this, - &CommandBufferStub::SwapBuffersCallback)); - processor_->SetTransportDIBAllocAndFree( - NewCallback(this, &CommandBufferStub::AllocTransportDIB), - NewCallback(this, &CommandBufferStub::FreeTransportDIB)); -#endif +void CommandBufferStub::OnInitialize(base::SharedMemoryHandle ring_buffer, + int32 size, + bool* result) { + // TODO(apatrick): Pepper3D v1 is not used anymore. This function is never + // called. Delete the GPU plugin. + NOTREACHED(); + *result = false; } void CommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) { diff --git a/chrome/plugin/command_buffer_stub.h b/chrome/plugin/command_buffer_stub.h index 96974ab..a2667f1 100644 --- a/chrome/plugin/command_buffer_stub.h +++ b/chrome/plugin/command_buffer_stub.h @@ -45,7 +45,9 @@ class CommandBufferStub : public IPC::Channel::Listener, private: // Message handlers: - void OnInitialize(int32 size, base::SharedMemoryHandle* ring_buffer); + void OnInitialize(base::SharedMemoryHandle ring_buffer, + int32 size, + bool* result); void OnGetState(gpu::CommandBuffer::State* state); void OnAsyncGetState(); void OnFlush(int32 put_offset, gpu::CommandBuffer::State* state); diff --git a/chrome/renderer/command_buffer_proxy.cc b/chrome/renderer/command_buffer_proxy.cc index 312cc7f..8414b4e 100644 --- a/chrome/renderer/command_buffer_proxy.cc +++ b/chrome/renderer/command_buffer_proxy.cc @@ -68,22 +68,62 @@ void CommandBufferProxy::SetChannelErrorCallback(Callback0::Type* callback) { bool CommandBufferProxy::Initialize(int32 size) { DCHECK(!ring_buffer_.get()); - // Initialize the service. Assuming we are sandboxed, the GPU - // process is responsible for duplicating the handle. This might not be true - // for NaCl. + RenderThread* render_thread = RenderThread::current(); + if (!render_thread) + return false; + base::SharedMemoryHandle handle; - if (Send(new GpuCommandBufferMsg_Initialize(route_id_, size, &handle)) && - base::SharedMemory::IsHandleValid(handle)) { - ring_buffer_.reset(new base::SharedMemory(handle, false)); - if (ring_buffer_->Map(size)) { - num_entries_ = size / sizeof(gpu::CommandBufferEntry); - return true; - } + if (!render_thread->Send(new ViewHostMsg_AllocateSharedMemoryBuffer( + size, + &handle))) { + return false; + } + + if (!base::SharedMemory::IsHandleValid(handle)) + return false; + +#if defined(OS_POSIX) + handle.auto_close = false; +#endif + // Take ownership of shared memory. This will close the handle if Send below + // fails. Otherwise, callee takes ownership before this variable + // goes out of scope. + base::SharedMemory shared_memory(handle, false); + + return Initialize(&shared_memory, size); +} + +bool CommandBufferProxy::Initialize(base::SharedMemory* buffer, int32 size) { + bool result; + if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, + buffer->handle(), + size, + &result))) { + LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; + return false; + } + + if (!result) { + LOG(ERROR) << "Failed to initialize command buffer service."; + return false; + } + + base::SharedMemoryHandle handle; + if (!buffer->GiveToProcess(base::GetCurrentProcessHandle(), &handle)) { + LOG(ERROR) << "Failed to duplicate command buffer handle."; + return false; + } + + ring_buffer_.reset(new base::SharedMemory(handle, false)); + if (!ring_buffer_->Map(size)) { + LOG(ERROR) << "Failed to map shared memory for command buffer."; ring_buffer_.reset(); + return false; } - return false; + num_entries_ = size / sizeof(gpu::CommandBufferEntry); + return true; } Buffer CommandBufferProxy::GetRingBuffer() { diff --git a/chrome/renderer/command_buffer_proxy.h b/chrome/renderer/command_buffer_proxy.h index bf5edc6..fa3994c 100644 --- a/chrome/renderer/command_buffer_proxy.h +++ b/chrome/renderer/command_buffer_proxy.h @@ -45,6 +45,7 @@ class CommandBufferProxy : public gpu::CommandBuffer, // CommandBuffer implementation: virtual bool Initialize(int32 size); + virtual bool Initialize(base::SharedMemory* buffer, int32 size); virtual gpu::Buffer GetRingBuffer(); virtual State GetState(); virtual void Flush(int32 put_offset); |