summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 23:36:54 +0000
committerapatrick@chromium.org <apatrick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-28 23:36:54 +0000
commit36dbfe198cb0eab50ff4a7300fc86b8314d30cde (patch)
treec7b2271be2e885ca87ac58d53e338cca322276a4 /chrome
parent406e6e22b82ef80e8bc44f45d85efa68799bc552 (diff)
downloadchromium_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.h5
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.cc90
-rw-r--r--chrome/gpu/gpu_command_buffer_stub.h4
-rw-r--r--chrome/plugin/command_buffer_stub.cc70
-rw-r--r--chrome/plugin/command_buffer_stub.h4
-rw-r--r--chrome/renderer/command_buffer_proxy.cc62
-rw-r--r--chrome/renderer/command_buffer_proxy.h1
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);