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 "ppapi/proxy/ppb_context_3d_proxy.h" | 5 #include "ppapi/proxy/ppb_context_3d_proxy.h" |
6 | 6 |
7 #include "base/hash_tables.h" | 7 #include "base/hash_tables.h" |
8 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | 8 #include "gpu/command_buffer/client/gles2_cmd_helper.h" |
9 #include "gpu/command_buffer/client/gles2_implementation.h" | 9 #include "gpu/command_buffer/client/gles2_implementation.h" |
10 #include "ppapi/c/pp_errors.h" | 10 #include "ppapi/c/pp_errors.h" |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 } | 148 } |
149 | 149 |
150 gpu::CommandBuffer::State GPUStateFromPPState( | 150 gpu::CommandBuffer::State GPUStateFromPPState( |
151 const PP_Context3DTrustedState& s) { | 151 const PP_Context3DTrustedState& s) { |
152 gpu::CommandBuffer::State state; | 152 gpu::CommandBuffer::State state; |
153 state.num_entries = s.num_entries; | 153 state.num_entries = s.num_entries; |
154 state.get_offset = s.get_offset; | 154 state.get_offset = s.get_offset; |
155 state.put_offset = s.put_offset; | 155 state.put_offset = s.put_offset; |
156 state.token = s.token; | 156 state.token = s.token; |
157 state.error = static_cast<gpu::error::Error>(s.error); | 157 state.error = static_cast<gpu::error::Error>(s.error); |
| 158 state.generation = s.generation; |
158 return state; | 159 return state; |
159 } | 160 } |
160 | 161 |
161 // Size of the transfer buffer. | 162 // Size of the transfer buffer. |
162 const int32 kCommandBufferSize = 1024 * 1024; | 163 const int32 kCommandBufferSize = 1024 * 1024; |
163 const int32 kTransferBufferSize = 1024 * 1024; | 164 const int32 kTransferBufferSize = 1024 * 1024; |
164 | 165 |
165 InterfaceProxy* CreateContext3DProxy(Dispatcher* dispatcher, | 166 InterfaceProxy* CreateContext3DProxy(Dispatcher* dispatcher, |
166 const void* target_interface) { | 167 const void* target_interface) { |
167 return new PPB_Context3D_Proxy(dispatcher, target_interface); | 168 return new PPB_Context3D_Proxy(dispatcher, target_interface); |
168 } | 169 } |
169 | 170 |
170 } // namespace | 171 } // namespace |
171 | 172 |
172 class PepperCommandBuffer : public gpu::CommandBuffer { | 173 class PepperCommandBuffer : public gpu::CommandBuffer { |
173 public: | 174 public: |
174 PepperCommandBuffer(const HostResource& resource, | 175 PepperCommandBuffer(const HostResource& resource, |
175 PluginDispatcher* dispatcher); | 176 PluginDispatcher* dispatcher); |
176 virtual ~PepperCommandBuffer(); | 177 virtual ~PepperCommandBuffer(); |
177 | 178 |
178 // CommandBuffer implementation: | 179 // CommandBuffer implementation: |
179 virtual bool Initialize(int32 size); | 180 virtual bool Initialize(int32 size); |
180 virtual bool Initialize(base::SharedMemory* buffer, int32 size); | 181 virtual bool Initialize(base::SharedMemory* buffer, int32 size); |
181 virtual gpu::Buffer GetRingBuffer(); | 182 virtual gpu::Buffer GetRingBuffer(); |
182 virtual State GetState(); | 183 virtual State GetState(); |
183 virtual void Flush(int32 put_offset); | 184 virtual void Flush(int32 put_offset); |
184 virtual State FlushSync(int32 put_offset); | 185 virtual State FlushSync(int32 put_offset, int32 last_known_get); |
185 virtual void SetGetOffset(int32 get_offset); | 186 virtual void SetGetOffset(int32 get_offset); |
186 virtual int32 CreateTransferBuffer(size_t size, int32 id_request); | 187 virtual int32 CreateTransferBuffer(size_t size, int32 id_request); |
187 virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, | 188 virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory, |
188 size_t size, | 189 size_t size, |
189 int32 id_request); | 190 int32 id_request); |
190 virtual void DestroyTransferBuffer(int32 id); | 191 virtual void DestroyTransferBuffer(int32 id); |
191 virtual gpu::Buffer GetTransferBuffer(int32 handle); | 192 virtual gpu::Buffer GetTransferBuffer(int32 handle); |
192 virtual void SetToken(int32 token); | 193 virtual void SetToken(int32 token); |
193 virtual void SetParseError(gpu::error::Error error); | 194 virtual void SetParseError(gpu::error::Error error); |
194 | 195 |
195 private: | 196 private: |
196 bool Send(IPC::Message* msg); | 197 bool Send(IPC::Message* msg); |
| 198 void UpdateState(const gpu::CommandBuffer::State& state); |
197 | 199 |
198 int32 num_entries_; | 200 int32 num_entries_; |
199 scoped_ptr<base::SharedMemory> ring_buffer_; | 201 scoped_ptr<base::SharedMemory> ring_buffer_; |
200 | 202 |
201 typedef base::hash_map<int32, gpu::Buffer> TransferBufferMap; | 203 typedef base::hash_map<int32, gpu::Buffer> TransferBufferMap; |
202 TransferBufferMap transfer_buffers_; | 204 TransferBufferMap transfer_buffers_; |
203 | 205 |
204 State last_state_; | 206 State last_state_; |
205 | 207 |
206 HostResource resource_; | 208 HostResource resource_; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 gpu::Buffer buffer; | 263 gpu::Buffer buffer; |
262 buffer.ptr = ring_buffer_->memory(); | 264 buffer.ptr = ring_buffer_->memory(); |
263 buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); | 265 buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); |
264 buffer.shared_memory = ring_buffer_.get(); | 266 buffer.shared_memory = ring_buffer_.get(); |
265 return buffer; | 267 return buffer; |
266 } | 268 } |
267 | 269 |
268 gpu::CommandBuffer::State PepperCommandBuffer::GetState() { | 270 gpu::CommandBuffer::State PepperCommandBuffer::GetState() { |
269 // Send will flag state with lost context if IPC fails. | 271 // Send will flag state with lost context if IPC fails. |
270 if (last_state_.error == gpu::error::kNoError) { | 272 if (last_state_.error == gpu::error::kNoError) { |
271 Send(new PpapiHostMsg_PPBContext3D_GetState( | 273 gpu::CommandBuffer::State state; |
272 INTERFACE_ID_PPB_CONTEXT_3D, resource_, &last_state_)); | 274 if (Send(new PpapiHostMsg_PPBContext3D_GetState( |
| 275 INTERFACE_ID_PPB_CONTEXT_3D, resource_, &state))) |
| 276 UpdateState(state); |
273 } | 277 } |
274 | 278 |
275 return last_state_; | 279 return last_state_; |
276 } | 280 } |
277 | 281 |
278 void PepperCommandBuffer::Flush(int32 put_offset) { | 282 void PepperCommandBuffer::Flush(int32 put_offset) { |
279 if (last_state_.error != gpu::error::kNoError) | 283 if (last_state_.error != gpu::error::kNoError) |
280 return; | 284 return; |
281 | 285 |
282 IPC::Message* message = new PpapiHostMsg_PPBContext3D_AsyncFlush( | 286 IPC::Message* message = new PpapiHostMsg_PPBContext3D_AsyncFlush( |
283 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset); | 287 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset); |
284 | 288 |
285 // Do not let a synchronous flush hold up this message. If this handler is | 289 // Do not let a synchronous flush hold up this message. If this handler is |
286 // deferred until after the synchronous flush completes, it will overwrite the | 290 // deferred until after the synchronous flush completes, it will overwrite the |
287 // cached last_state_ with out-of-date data. | 291 // cached last_state_ with out-of-date data. |
288 message->set_unblock(true); | 292 message->set_unblock(true); |
289 Send(message); | 293 Send(message); |
290 } | 294 } |
291 | 295 |
292 gpu::CommandBuffer::State PepperCommandBuffer::FlushSync(int32 put_offset) { | 296 gpu::CommandBuffer::State PepperCommandBuffer::FlushSync( |
293 // Send will flag state with lost context if IPC fails. | 297 int32 put_offset, int32 last_known_get) { |
294 if (last_state_.error == gpu::error::kNoError) { | 298 if (last_known_get == last_state_.get_offset) { |
295 Send(new PpapiHostMsg_PPBContext3D_Flush( | 299 // Send will flag state with lost context if IPC fails. |
296 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset, &last_state_)); | 300 if (last_state_.error == gpu::error::kNoError) { |
| 301 gpu::CommandBuffer::State state; |
| 302 if (Send(new PpapiHostMsg_PPBContext3D_Flush( |
| 303 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset, |
| 304 last_known_get, &state))) |
| 305 UpdateState(state); |
| 306 } |
| 307 } else { |
| 308 Flush(put_offset); |
297 } | 309 } |
298 | 310 |
299 return last_state_; | 311 return last_state_; |
300 } | 312 } |
301 | 313 |
302 void PepperCommandBuffer::SetGetOffset(int32 get_offset) { | 314 void PepperCommandBuffer::SetGetOffset(int32 get_offset) { |
303 // Not implemented in proxy. | 315 // Not implemented in proxy. |
304 NOTREACHED(); | 316 NOTREACHED(); |
305 } | 317 } |
306 | 318 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 bool PepperCommandBuffer::Send(IPC::Message* msg) { | 405 bool PepperCommandBuffer::Send(IPC::Message* msg) { |
394 DCHECK(last_state_.error == gpu::error::kNoError); | 406 DCHECK(last_state_.error == gpu::error::kNoError); |
395 | 407 |
396 if (dispatcher_->Send(msg)) | 408 if (dispatcher_->Send(msg)) |
397 return true; | 409 return true; |
398 | 410 |
399 last_state_.error = gpu::error::kLostContext; | 411 last_state_.error = gpu::error::kLostContext; |
400 return false; | 412 return false; |
401 } | 413 } |
402 | 414 |
| 415 void PepperCommandBuffer::UpdateState(const gpu::CommandBuffer::State& state) { |
| 416 // Handle wraparound. It works as long as we don't have more than 2B state |
| 417 // updates in flight across which reordering occurs. |
| 418 if (state.generation - last_state_.generation < 0x80000000U) |
| 419 last_state_ = state; |
| 420 } |
| 421 |
403 Context3D::Context3D(const HostResource& resource) | 422 Context3D::Context3D(const HostResource& resource) |
404 : PluginResource(resource), | 423 : PluginResource(resource), |
405 draw_(NULL), | 424 draw_(NULL), |
406 read_(NULL), | 425 read_(NULL), |
407 transfer_buffer_id_(0) { | 426 transfer_buffer_id_(0) { |
408 } | 427 } |
409 | 428 |
410 Context3D::~Context3D() { | 429 Context3D::~Context3D() { |
411 if (draw_) | 430 if (draw_) |
412 draw_->set_context(NULL); | 431 draw_->set_context(NULL); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
564 | 583 |
565 void PPB_Context3D_Proxy::OnMsgGetState(const HostResource& context, | 584 void PPB_Context3D_Proxy::OnMsgGetState(const HostResource& context, |
566 gpu::CommandBuffer::State* state) { | 585 gpu::CommandBuffer::State* state) { |
567 PP_Context3DTrustedState pp_state = | 586 PP_Context3DTrustedState pp_state = |
568 ppb_context_3d_trusted()->GetState(context.host_resource()); | 587 ppb_context_3d_trusted()->GetState(context.host_resource()); |
569 *state = GPUStateFromPPState(pp_state); | 588 *state = GPUStateFromPPState(pp_state); |
570 } | 589 } |
571 | 590 |
572 void PPB_Context3D_Proxy::OnMsgFlush(const HostResource& context, | 591 void PPB_Context3D_Proxy::OnMsgFlush(const HostResource& context, |
573 int32 put_offset, | 592 int32 put_offset, |
| 593 int32 last_known_get, |
574 gpu::CommandBuffer::State* state) { | 594 gpu::CommandBuffer::State* state) { |
575 PP_Context3DTrustedState pp_state = | 595 PP_Context3DTrustedState pp_state = ppb_context_3d_trusted()->FlushSyncFast( |
576 ppb_context_3d_trusted()->FlushSync(context.host_resource(), put_offset); | 596 context.host_resource(), put_offset, last_known_get); |
577 *state = GPUStateFromPPState(pp_state); | 597 *state = GPUStateFromPPState(pp_state); |
578 } | 598 } |
579 | 599 |
580 void PPB_Context3D_Proxy::OnMsgAsyncFlush(const HostResource& context, | 600 void PPB_Context3D_Proxy::OnMsgAsyncFlush(const HostResource& context, |
581 int32 put_offset) { | 601 int32 put_offset) { |
582 ppb_context_3d_trusted()->Flush(context.host_resource(), put_offset); | 602 ppb_context_3d_trusted()->Flush(context.host_resource(), put_offset); |
583 } | 603 } |
584 | 604 |
585 void PPB_Context3D_Proxy::OnMsgCreateTransferBuffer( | 605 void PPB_Context3D_Proxy::OnMsgCreateTransferBuffer( |
586 const HostResource& context, | 606 const HostResource& context, |
(...skipping 22 matching lines...) Expand all Loading... |
609 &shm_handle, | 629 &shm_handle, |
610 &shm_size)) { | 630 &shm_size)) { |
611 return; | 631 return; |
612 } | 632 } |
613 *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle); | 633 *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle); |
614 *size = shm_size; | 634 *size = shm_size; |
615 } | 635 } |
616 | 636 |
617 } // namespace proxy | 637 } // namespace proxy |
618 } // namespace pp | 638 } // namespace pp |
OLD | NEW |