1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
7 #include "ppapi/proxy/ppapi_messages.h"
8 #include "ppapi/proxy/proxy_channel.h"
9 #include "ppapi/shared_impl/api_id.h"
10 #include "ppapi/shared_impl/host_resource.h"
11 #include "ppapi/shared_impl/proxy_lock.h"
16 PpapiCommandBufferProxy::PpapiCommandBufferProxy(
17 const ppapi::HostResource
& resource
,
18 ProxyChannel
* channel
)
19 : resource_(resource
),
23 PpapiCommandBufferProxy::~PpapiCommandBufferProxy() {
24 // gpu::Buffers are no longer referenced, allowing shared memory objects to be
25 // deleted, closing the handle in this process.
28 bool PpapiCommandBufferProxy::Initialize() {
32 gpu::CommandBuffer::State
PpapiCommandBufferProxy::GetLastState() {
33 ppapi::ProxyLock::AssertAcquiredDebugOnly();
37 int32
PpapiCommandBufferProxy::GetLastToken() {
38 ppapi::ProxyLock::AssertAcquiredDebugOnly();
39 return last_state_
.token
;
42 void PpapiCommandBufferProxy::Flush(int32 put_offset
) {
43 if (last_state_
.error
!= gpu::error::kNoError
)
46 IPC::Message
* message
= new PpapiHostMsg_PPBGraphics3D_AsyncFlush(
47 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, put_offset
);
49 // Do not let a synchronous flush hold up this message. If this handler is
50 // deferred until after the synchronous flush completes, it will overwrite the
51 // cached last_state_ with out-of-date data.
52 message
->set_unblock(true);
56 void PpapiCommandBufferProxy::WaitForTokenInRange(int32 start
, int32 end
) {
57 if (last_state_
.error
!= gpu::error::kNoError
)
61 gpu::CommandBuffer::State state
;
62 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange(
63 ppapi::API_ID_PPB_GRAPHICS_3D
,
69 UpdateState(state
, success
);
72 void PpapiCommandBufferProxy::WaitForGetOffsetInRange(int32 start
, int32 end
) {
73 if (last_state_
.error
!= gpu::error::kNoError
)
77 gpu::CommandBuffer::State state
;
78 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange(
79 ppapi::API_ID_PPB_GRAPHICS_3D
,
85 UpdateState(state
, success
);
88 void PpapiCommandBufferProxy::SetGetBuffer(int32 transfer_buffer_id
) {
89 if (last_state_
.error
== gpu::error::kNoError
) {
90 Send(new PpapiHostMsg_PPBGraphics3D_SetGetBuffer(
91 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, transfer_buffer_id
));
95 scoped_refptr
<gpu::Buffer
> PpapiCommandBufferProxy::CreateTransferBuffer(
100 if (last_state_
.error
!= gpu::error::kNoError
)
103 // Assuming we are in the renderer process, the service is responsible for
104 // duplicating the handle. This might not be true for NaCl.
105 ppapi::proxy::SerializedHandle
handle(
106 ppapi::proxy::SerializedHandle::SHARED_MEMORY
);
107 if (!Send(new PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer(
108 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, size
, id
, &handle
))) {
112 if (*id
<= 0 || !handle
.is_shmem())
115 scoped_ptr
<base::SharedMemory
> shared_memory(
116 new base::SharedMemory(handle
.shmem(), false));
118 // Map the shared memory on demand.
119 if (!shared_memory
->memory()) {
120 if (!shared_memory
->Map(handle
.size())) {
126 return gpu::MakeBufferFromSharedMemory(shared_memory
.Pass(), handle
.size());
129 void PpapiCommandBufferProxy::DestroyTransferBuffer(int32 id
) {
130 if (last_state_
.error
!= gpu::error::kNoError
)
133 Send(new PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer(
134 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, id
));
137 void PpapiCommandBufferProxy::Echo(const base::Closure
& callback
) {
141 uint32
PpapiCommandBufferProxy::CreateStreamTexture(uint32 texture_id
) {
146 uint32
PpapiCommandBufferProxy::InsertSyncPoint() {
147 uint32 sync_point
= 0;
148 if (last_state_
.error
== gpu::error::kNoError
) {
149 Send(new PpapiHostMsg_PPBGraphics3D_InsertSyncPoint(
150 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, &sync_point
));
155 uint32
PpapiCommandBufferProxy::InsertFutureSyncPoint() {
156 uint32 sync_point
= 0;
157 if (last_state_
.error
== gpu::error::kNoError
) {
158 Send(new PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint(
159 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, &sync_point
));
164 void PpapiCommandBufferProxy::RetireSyncPoint(uint32 sync_point
) {
165 if (last_state_
.error
== gpu::error::kNoError
) {
166 Send(new PpapiHostMsg_PPBGraphics3D_RetireSyncPoint(
167 ppapi::API_ID_PPB_GRAPHICS_3D
, resource_
, sync_point
));
171 void PpapiCommandBufferProxy::SignalSyncPoint(uint32 sync_point
,
172 const base::Closure
& callback
) {
176 void PpapiCommandBufferProxy::SignalQuery(uint32 query
,
177 const base::Closure
& callback
) {
181 void PpapiCommandBufferProxy::SetSurfaceVisible(bool visible
) {
185 gpu::Capabilities
PpapiCommandBufferProxy::GetCapabilities() {
186 // TODO(boliu): Need to implement this to use cc in Pepper. Tracked in
188 return gpu::Capabilities();
191 gfx::GpuMemoryBuffer
* PpapiCommandBufferProxy::CreateGpuMemoryBuffer(
194 unsigned internalformat
,
201 void PpapiCommandBufferProxy::DestroyGpuMemoryBuffer(int32 id
) {
205 bool PpapiCommandBufferProxy::Send(IPC::Message
* msg
) {
206 DCHECK(last_state_
.error
== gpu::error::kNoError
);
208 if (channel_
->Send(msg
))
211 last_state_
.error
= gpu::error::kLostContext
;
215 void PpapiCommandBufferProxy::UpdateState(
216 const gpu::CommandBuffer::State
& state
,
218 // Handle wraparound. It works as long as we don't have more than 2B state
219 // updates in flight across which reordering occurs.
221 if (state
.generation
- last_state_
.generation
< 0x80000000U
) {
225 last_state_
.error
= gpu::error::kLostContext
;
226 ++last_state_
.generation
;