OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/gpu/command_buffer_proxy.h" | 5 #include "content/renderer/gpu/command_buffer_proxy.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/process_util.h" | 9 #include "base/process_util.h" |
10 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/task.h" | 12 #include "base/task.h" |
13 #include "content/common/child_process_messages.h" | 13 #include "content/common/child_process_messages.h" |
14 #include "content/common/child_thread.h" | 14 #include "content/common/child_thread.h" |
15 #include "content/common/gpu/gpu_messages.h" | 15 #include "content/common/gpu/gpu_messages.h" |
16 #include "content/common/plugin_messages.h" | 16 #include "content/common/plugin_messages.h" |
17 #include "content/common/view_messages.h" | 17 #include "content/common/view_messages.h" |
18 #include "content/renderer/gpu/gpu_channel_host.h" | 18 #include "content/renderer/gpu/gpu_channel_host.h" |
19 #include "content/renderer/plugin_channel_host.h" | 19 #include "content/renderer/plugin_channel_host.h" |
20 #include "gpu/command_buffer/common/cmd_buffer_common.h" | 20 #include "gpu/command_buffer/common/cmd_buffer_common.h" |
21 #include "ui/gfx/size.h" | 21 #include "ui/gfx/size.h" |
22 | 22 |
23 using gpu::Buffer; | 23 using gpu::Buffer; |
24 | 24 |
25 CommandBufferProxy::CommandBufferProxy( | 25 CommandBufferProxy::CommandBufferProxy( |
26 GpuChannelHost* channel, | 26 GpuChannelHost* channel, |
27 int route_id) | 27 int route_id) |
28 : channel_(channel), | 28 : num_entries_(0), |
| 29 channel_(channel), |
29 route_id_(route_id), | 30 route_id_(route_id), |
30 flush_count_(0) { | 31 flush_count_(0) { |
31 } | 32 } |
32 | 33 |
33 CommandBufferProxy::~CommandBufferProxy() { | 34 CommandBufferProxy::~CommandBufferProxy() { |
34 // Delete all the locally cached shared memory objects, closing the handle | 35 // Delete all the locally cached shared memory objects, closing the handle |
35 // in this process. | 36 // in this process. |
36 for (TransferBufferMap::iterator it = transfer_buffers_.begin(); | 37 for (TransferBufferMap::iterator it = transfer_buffers_.begin(); |
37 it != transfer_buffers_.end(); | 38 it != transfer_buffers_.end(); |
38 ++it) { | 39 ++it) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 base::Closure callback = echo_tasks_.front(); | 86 base::Closure callback = echo_tasks_.front(); |
86 echo_tasks_.pop(); | 87 echo_tasks_.pop(); |
87 callback.Run(); | 88 callback.Run(); |
88 } | 89 } |
89 | 90 |
90 void CommandBufferProxy::SetChannelErrorCallback( | 91 void CommandBufferProxy::SetChannelErrorCallback( |
91 const base::Closure& callback) { | 92 const base::Closure& callback) { |
92 channel_error_callback_ = callback; | 93 channel_error_callback_ = callback; |
93 } | 94 } |
94 | 95 |
95 bool CommandBufferProxy::Initialize() { | 96 bool CommandBufferProxy::Initialize(int32 size) { |
| 97 DCHECK(!ring_buffer_.get()); |
| 98 |
96 ChildThread* child_thread = ChildThread::current(); | 99 ChildThread* child_thread = ChildThread::current(); |
97 if (!child_thread) | 100 if (!child_thread) |
98 return false; | 101 return false; |
99 | 102 |
| 103 base::SharedMemoryHandle handle; |
| 104 if (!child_thread->Send(new ChildProcessHostMsg_SyncAllocateSharedMemory( |
| 105 size, |
| 106 &handle))) { |
| 107 return false; |
| 108 } |
| 109 |
| 110 if (!base::SharedMemory::IsHandleValid(handle)) |
| 111 return false; |
| 112 |
| 113 #if defined(OS_POSIX) |
| 114 handle.auto_close = false; |
| 115 #endif |
| 116 |
| 117 // Take ownership of shared memory. This will close the handle if Send below |
| 118 // fails. Otherwise, callee takes ownership before this variable |
| 119 // goes out of scope. |
| 120 base::SharedMemory shared_memory(handle, false); |
| 121 |
| 122 return Initialize(&shared_memory, size); |
| 123 } |
| 124 |
| 125 bool CommandBufferProxy::Initialize(base::SharedMemory* buffer, int32 size) { |
100 bool result; | 126 bool result; |
101 if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, &result))) { | 127 if (!Send(new GpuCommandBufferMsg_Initialize(route_id_, |
| 128 buffer->handle(), |
| 129 size, |
| 130 &result))) { |
102 LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; | 131 LOG(ERROR) << "Could not send GpuCommandBufferMsg_Initialize."; |
103 return false; | 132 return false; |
104 } | 133 } |
105 | 134 |
106 if (!result) { | 135 if (!result) { |
107 LOG(ERROR) << "Failed to initialize command buffer service."; | 136 LOG(ERROR) << "Failed to initialize command buffer service."; |
108 return false; | 137 return false; |
109 } | 138 } |
110 | 139 |
| 140 base::SharedMemoryHandle handle; |
| 141 if (!buffer->GiveToProcess(base::GetCurrentProcessHandle(), &handle)) { |
| 142 LOG(ERROR) << "Failed to duplicate command buffer handle."; |
| 143 return false; |
| 144 } |
| 145 |
| 146 ring_buffer_.reset(new base::SharedMemory(handle, false)); |
| 147 if (!ring_buffer_->Map(size)) { |
| 148 LOG(ERROR) << "Failed to map shared memory for command buffer."; |
| 149 ring_buffer_.reset(); |
| 150 return false; |
| 151 } |
| 152 |
| 153 num_entries_ = size / sizeof(gpu::CommandBufferEntry); |
111 return true; | 154 return true; |
112 } | 155 } |
113 | 156 |
| 157 Buffer CommandBufferProxy::GetRingBuffer() { |
| 158 DCHECK(ring_buffer_.get()); |
| 159 // Return locally cached ring buffer. |
| 160 Buffer buffer; |
| 161 if (ring_buffer_.get()) { |
| 162 buffer.ptr = ring_buffer_->memory(); |
| 163 buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); |
| 164 buffer.shared_memory = ring_buffer_.get(); |
| 165 } else { |
| 166 buffer.ptr = NULL; |
| 167 buffer.size = 0; |
| 168 buffer.shared_memory = NULL; |
| 169 } |
| 170 return buffer; |
| 171 } |
| 172 |
114 gpu::CommandBuffer::State CommandBufferProxy::GetState() { | 173 gpu::CommandBuffer::State CommandBufferProxy::GetState() { |
115 // Send will flag state with lost context if IPC fails. | 174 // Send will flag state with lost context if IPC fails. |
116 if (last_state_.error == gpu::error::kNoError) { | 175 if (last_state_.error == gpu::error::kNoError) { |
117 gpu::CommandBuffer::State state; | 176 gpu::CommandBuffer::State state; |
118 if (Send(new GpuCommandBufferMsg_GetState(route_id_, &state))) | 177 if (Send(new GpuCommandBufferMsg_GetState(route_id_, &state))) |
119 OnUpdateState(state); | 178 OnUpdateState(state); |
120 } | 179 } |
121 | 180 |
122 return last_state_; | 181 return last_state_; |
123 } | 182 } |
(...skipping 24 matching lines...) Expand all Loading... |
148 gpu::CommandBuffer::State state; | 207 gpu::CommandBuffer::State state; |
149 if (Send(new GpuCommandBufferMsg_GetStateFast(route_id_, | 208 if (Send(new GpuCommandBufferMsg_GetStateFast(route_id_, |
150 &state))) | 209 &state))) |
151 OnUpdateState(state); | 210 OnUpdateState(state); |
152 } | 211 } |
153 } | 212 } |
154 | 213 |
155 return last_state_; | 214 return last_state_; |
156 } | 215 } |
157 | 216 |
158 void CommandBufferProxy::SetGetBuffer(int32 shm_id) { | |
159 if (last_state_.error != gpu::error::kNoError) | |
160 return; | |
161 | |
162 Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id)); | |
163 } | |
164 | |
165 void CommandBufferProxy::SetGetOffset(int32 get_offset) { | 217 void CommandBufferProxy::SetGetOffset(int32 get_offset) { |
166 // Not implemented in proxy. | 218 // Not implemented in proxy. |
167 NOTREACHED(); | 219 NOTREACHED(); |
168 } | 220 } |
169 | 221 |
170 int32 CommandBufferProxy::CreateTransferBuffer(size_t size, int32 id_request) { | 222 int32 CommandBufferProxy::CreateTransferBuffer(size_t size, int32 id_request) { |
171 if (last_state_.error != gpu::error::kNoError) | 223 if (last_state_.error != gpu::error::kNoError) |
172 return -1; | 224 return -1; |
173 | 225 |
174 ChildThread* child_thread = ChildThread::current(); | 226 ChildThread* child_thread = ChildThread::current(); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 delete msg; | 457 delete msg; |
406 return false; | 458 return false; |
407 } | 459 } |
408 | 460 |
409 void CommandBufferProxy::OnUpdateState(const gpu::CommandBuffer::State& state) { | 461 void CommandBufferProxy::OnUpdateState(const gpu::CommandBuffer::State& state) { |
410 // Handle wraparound. It works as long as we don't have more than 2B state | 462 // Handle wraparound. It works as long as we don't have more than 2B state |
411 // updates in flight across which reordering occurs. | 463 // updates in flight across which reordering occurs. |
412 if (state.generation - last_state_.generation < 0x80000000U) | 464 if (state.generation - last_state_.generation < 0x80000000U) |
413 last_state_ = state; | 465 last_state_ = state; |
414 } | 466 } |
OLD | NEW |