| 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 |