diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.cc | 27 | ||||
-rw-r--r-- | content/common/gpu/gpu_command_buffer_stub.h | 5 | ||||
-rw-r--r-- | content/common/gpu/gpu_messages.h | 8 | ||||
-rw-r--r-- | content/renderer/gpu/command_buffer_proxy.cc | 72 | ||||
-rw-r--r-- | content/renderer/gpu/command_buffer_proxy.h | 9 | ||||
-rw-r--r-- | content/renderer/gpu/renderer_gl_context.cc | 2 |
6 files changed, 91 insertions, 32 deletions
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc index 0fee183..af478e0 100644 --- a/content/common/gpu/gpu_command_buffer_stub.cc +++ b/content/common/gpu/gpu_command_buffer_stub.cc @@ -87,8 +87,6 @@ bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_Initialize, OnInitialize); - IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetGetBuffer, - OnSetGetBuffer); IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_SetParent, OnSetParent); IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuCommandBufferMsg_GetState, OnGetState); @@ -161,6 +159,8 @@ void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { } void GpuCommandBufferStub::OnInitialize( + base::SharedMemoryHandle ring_buffer, + int32 size, IPC::Message* reply_message) { DCHECK(!command_buffer_.get()); @@ -168,7 +168,19 @@ void GpuCommandBufferStub::OnInitialize( command_buffer_.reset(new gpu::CommandBufferService); - if (!command_buffer_->Initialize()) { +#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 + + if (!command_buffer_->Initialize(&shared_memory, size)) { DLOG(ERROR) << "CommandBufferService failed to initialize.\n"; OnInitializeFailed(reply_message); return; @@ -250,9 +262,6 @@ void GpuCommandBufferStub::OnInitialize( command_buffer_->SetPutOffsetChangeCallback( base::Bind(&gpu::GpuScheduler::PutChanged, base::Unretained(scheduler_.get()))); - command_buffer_->SetGetBufferChangeCallback( - base::Bind(&gpu::GpuScheduler::SetGetBuffer, - base::Unretained(scheduler_.get()))); command_buffer_->SetParseErrorCallback( base::Bind(&GpuCommandBufferStub::OnParseError, base::Unretained(this))); scheduler_->SetScheduledCallback( @@ -278,12 +287,6 @@ void GpuCommandBufferStub::OnInitialize( "offscreen", surface_->IsOffscreen()); } -void GpuCommandBufferStub::OnSetGetBuffer( - int32 shm_id, IPC::Message* reply_message) { - command_buffer_->SetGetBuffer(shm_id); - Send(reply_message); -} - void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, uint32 parent_texture_id, IPC::Message* reply_message) { diff --git a/content/common/gpu/gpu_command_buffer_stub.h b/content/common/gpu/gpu_command_buffer_stub.h index 2124192..f581593 100644 --- a/content/common/gpu/gpu_command_buffer_stub.h +++ b/content/common/gpu/gpu_command_buffer_stub.h @@ -90,8 +90,9 @@ class GpuCommandBufferStub void OnInitializeFailed(IPC::Message* reply_message); // Message handlers: - void OnInitialize(IPC::Message* reply_message); - void OnSetGetBuffer(int32 shm_id, IPC::Message* reply_message); + void OnInitialize(base::SharedMemoryHandle ring_buffer, + int32 size, + IPC::Message* reply_message); void OnSetParent(int32 parent_route_id, uint32 parent_texture_id, IPC::Message* reply_message); diff --git a/content/common/gpu/gpu_messages.h b/content/common/gpu/gpu_messages.h index 7099747..e5cab60 100644 --- a/content/common/gpu/gpu_messages.h +++ b/content/common/gpu/gpu_messages.h @@ -311,13 +311,11 @@ IPC_MESSAGE_CONTROL0(GpuChannelMsg_CloseChannel) // 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_ROUTED0_1(GpuCommandBufferMsg_Initialize, +IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_Initialize, + base::SharedMemoryHandle /* ring_buffer */, + int32 /* size */, bool /* result */) -// Sets the shared memory buffer used for commands. -IPC_SYNC_MESSAGE_ROUTED1_0(GpuCommandBufferMsg_SetGetBuffer, - int32 /* shm_id */) - // Sets the parent command buffer. This allows the parent and child to share // textures. IPC_SYNC_MESSAGE_ROUTED2_1(GpuCommandBufferMsg_SetParent, diff --git a/content/renderer/gpu/command_buffer_proxy.cc b/content/renderer/gpu/command_buffer_proxy.cc index d51f840..86420ae 100644 --- a/content/renderer/gpu/command_buffer_proxy.cc +++ b/content/renderer/gpu/command_buffer_proxy.cc @@ -25,7 +25,8 @@ using gpu::Buffer; CommandBufferProxy::CommandBufferProxy( GpuChannelHost* channel, int route_id) - : channel_(channel), + : num_entries_(0), + channel_(channel), route_id_(route_id), flush_count_(0) { } @@ -92,13 +93,41 @@ void CommandBufferProxy::SetChannelErrorCallback( channel_error_callback_ = callback; } -bool CommandBufferProxy::Initialize() { +bool CommandBufferProxy::Initialize(int32 size) { + DCHECK(!ring_buffer_.get()); + ChildThread* child_thread = ChildThread::current(); if (!child_thread) return false; + base::SharedMemoryHandle handle; + if (!child_thread->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( + 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_, &result))) { + if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, + buffer->handle(), + size, + &result))) { LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; return false; } @@ -108,9 +137,39 @@ bool CommandBufferProxy::Initialize() { 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; + } + + num_entries_ = size / sizeof(gpu::CommandBufferEntry); return true; } +Buffer CommandBufferProxy::GetRingBuffer() { + DCHECK(ring_buffer_.get()); + // Return locally cached ring buffer. + Buffer buffer; + if (ring_buffer_.get()) { + buffer.ptr = ring_buffer_->memory(); + buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); + buffer.shared_memory = ring_buffer_.get(); + } else { + buffer.ptr = NULL; + buffer.size = 0; + buffer.shared_memory = NULL; + } + return buffer; +} + gpu::CommandBuffer::State CommandBufferProxy::GetState() { // Send will flag state with lost context if IPC fails. if (last_state_.error == gpu::error::kNoError) { @@ -155,13 +214,6 @@ gpu::CommandBuffer::State CommandBufferProxy::FlushSync(int32 put_offset, return last_state_; } -void CommandBufferProxy::SetGetBuffer(int32 shm_id) { - if (last_state_.error != gpu::error::kNoError) - return; - - Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id)); -} - void CommandBufferProxy::SetGetOffset(int32 get_offset) { // Not implemented in proxy. NOTREACHED(); diff --git a/content/renderer/gpu/command_buffer_proxy.h b/content/renderer/gpu/command_buffer_proxy.h index 6591621..551e1ca 100644 --- a/content/renderer/gpu/command_buffer_proxy.h +++ b/content/renderer/gpu/command_buffer_proxy.h @@ -43,12 +43,13 @@ class CommandBufferProxy : public gpu::CommandBuffer, int route_id() const { return route_id_; } // CommandBuffer implementation: - virtual bool Initialize() OVERRIDE; + virtual bool Initialize(int32 size) OVERRIDE; + virtual bool Initialize(base::SharedMemory* buffer, int32 size) OVERRIDE; + virtual gpu::Buffer GetRingBuffer() OVERRIDE; virtual State GetState() OVERRIDE; virtual State GetLastState() OVERRIDE; virtual void Flush(int32 put_offset) OVERRIDE; virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE; - virtual void SetGetBuffer(int32 shm_id) OVERRIDE; virtual void SetGetOffset(int32 get_offset) OVERRIDE; virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE; virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, @@ -103,6 +104,10 @@ class CommandBufferProxy : public gpu::CommandBuffer, void OnDestroyed(gpu::error::ContextLostReason reason); void OnEchoAck(); + // As with the service, the client takes ownership of the ring buffer. + int32 num_entries_; + scoped_ptr<base::SharedMemory> ring_buffer_; + // Local cache of id to transfer buffer mapping. typedef std::map<int32, gpu::Buffer> TransferBufferMap; TransferBufferMap transfer_buffers_; diff --git a/content/renderer/gpu/renderer_gl_context.cc b/content/renderer/gpu/renderer_gl_context.cc index 8fa9262..03f6715 100644 --- a/content/renderer/gpu/renderer_gl_context.cc +++ b/content/renderer/gpu/renderer_gl_context.cc @@ -380,7 +380,7 @@ bool RendererGLContext::Initialize(bool onscreen, TRACE_EVENT0("gpu", "RendererGLContext::Initialize::InitializeCommandBuffer"); // Initiaize the command buffer. - if (!command_buffer_->Initialize()) { + if (!command_buffer_->Initialize(kCommandBufferSize)) { Destroy(); return false; } |