Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / ppapi / proxy / ppapi_command_buffer_proxy.cc
blob7a42524bff2fe2827ffbce153f9d62f1a011b108
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 "base/numerics/safe_conversions.h"
8 #include "ppapi/proxy/ppapi_messages.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"
13 namespace ppapi {
14 namespace proxy {
16 PpapiCommandBufferProxy::PpapiCommandBufferProxy(
17 const ppapi::HostResource& resource,
18 PluginDispatcher* dispatcher,
19 const gpu::Capabilities& capabilities,
20 const SerializedHandle& shared_state)
21 : capabilities_(capabilities),
22 resource_(resource),
23 dispatcher_(dispatcher) {
24 shared_state_shm_.reset(
25 new base::SharedMemory(shared_state.shmem(), false));
26 shared_state_shm_->Map(shared_state.size());
27 InstanceData* data = dispatcher->GetInstanceData(resource.instance());
28 flush_info_ = &data->flush_info_;
31 PpapiCommandBufferProxy::~PpapiCommandBufferProxy() {
32 // gpu::Buffers are no longer referenced, allowing shared memory objects to be
33 // deleted, closing the handle in this process.
36 bool PpapiCommandBufferProxy::Initialize() {
37 return true;
40 gpu::CommandBuffer::State PpapiCommandBufferProxy::GetLastState() {
41 ppapi::ProxyLock::AssertAcquiredDebugOnly();
42 return last_state_;
45 int32 PpapiCommandBufferProxy::GetLastToken() {
46 ppapi::ProxyLock::AssertAcquiredDebugOnly();
47 TryUpdateState();
48 return last_state_.token;
51 void PpapiCommandBufferProxy::Flush(int32 put_offset) {
52 if (last_state_.error != gpu::error::kNoError)
53 return;
55 OrderingBarrier(put_offset);
56 FlushInternal();
59 void PpapiCommandBufferProxy::OrderingBarrier(int32 put_offset) {
60 if (last_state_.error != gpu::error::kNoError)
61 return;
63 if (flush_info_->flush_pending && flush_info_->resource != resource_)
64 FlushInternal();
66 flush_info_->flush_pending = true;
67 flush_info_->resource = resource_;
68 flush_info_->put_offset = put_offset;
71 void PpapiCommandBufferProxy::WaitForTokenInRange(int32 start, int32 end) {
72 TryUpdateState();
73 if (!InRange(start, end, last_state_.token) &&
74 last_state_.error == gpu::error::kNoError) {
75 bool success = false;
76 gpu::CommandBuffer::State state;
77 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange(
78 ppapi::API_ID_PPB_GRAPHICS_3D,
79 resource_,
80 start,
81 end,
82 &state,
83 &success)))
84 UpdateState(state, success);
86 DCHECK(InRange(start, end, last_state_.token) ||
87 last_state_.error != gpu::error::kNoError);
90 void PpapiCommandBufferProxy::WaitForGetOffsetInRange(int32 start, int32 end) {
91 TryUpdateState();
92 if (!InRange(start, end, last_state_.get_offset) &&
93 last_state_.error == gpu::error::kNoError) {
94 bool success = false;
95 gpu::CommandBuffer::State state;
96 if (Send(new PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange(
97 ppapi::API_ID_PPB_GRAPHICS_3D,
98 resource_,
99 start,
100 end,
101 &state,
102 &success)))
103 UpdateState(state, success);
105 DCHECK(InRange(start, end, last_state_.get_offset) ||
106 last_state_.error != gpu::error::kNoError);
109 void PpapiCommandBufferProxy::SetGetBuffer(int32 transfer_buffer_id) {
110 if (last_state_.error == gpu::error::kNoError) {
111 Send(new PpapiHostMsg_PPBGraphics3D_SetGetBuffer(
112 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, transfer_buffer_id));
116 scoped_refptr<gpu::Buffer> PpapiCommandBufferProxy::CreateTransferBuffer(
117 size_t size,
118 int32* id) {
119 *id = -1;
121 if (last_state_.error != gpu::error::kNoError)
122 return NULL;
124 // Assuming we are in the renderer process, the service is responsible for
125 // duplicating the handle. This might not be true for NaCl.
126 ppapi::proxy::SerializedHandle handle(
127 ppapi::proxy::SerializedHandle::SHARED_MEMORY);
128 if (!Send(new PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer(
129 ppapi::API_ID_PPB_GRAPHICS_3D, resource_,
130 base::checked_cast<uint32_t>(size), id, &handle))) {
131 if (last_state_.error == gpu::error::kNoError)
132 last_state_.error = gpu::error::kLostContext;
133 return NULL;
136 if (*id <= 0 || !handle.is_shmem()) {
137 if (last_state_.error == gpu::error::kNoError)
138 last_state_.error = gpu::error::kOutOfBounds;
139 return NULL;
142 scoped_ptr<base::SharedMemory> shared_memory(
143 new base::SharedMemory(handle.shmem(), false));
145 // Map the shared memory on demand.
146 if (!shared_memory->memory()) {
147 if (!shared_memory->Map(handle.size())) {
148 if (last_state_.error == gpu::error::kNoError)
149 last_state_.error = gpu::error::kOutOfBounds;
150 *id = -1;
151 return NULL;
155 return gpu::MakeBufferFromSharedMemory(shared_memory.Pass(), handle.size());
158 void PpapiCommandBufferProxy::DestroyTransferBuffer(int32 id) {
159 if (last_state_.error != gpu::error::kNoError)
160 return;
162 Send(new PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer(
163 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, id));
166 uint32 PpapiCommandBufferProxy::CreateStreamTexture(uint32 texture_id) {
167 NOTREACHED();
168 return 0;
171 void PpapiCommandBufferProxy::SetLock(base::Lock*) {
172 NOTIMPLEMENTED();
175 bool PpapiCommandBufferProxy::IsGpuChannelLost() {
176 NOTIMPLEMENTED();
177 return false;
180 uint32 PpapiCommandBufferProxy::InsertSyncPoint() {
181 uint32 sync_point = 0;
182 if (last_state_.error == gpu::error::kNoError) {
183 Send(new PpapiHostMsg_PPBGraphics3D_InsertSyncPoint(
184 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, &sync_point));
186 return sync_point;
189 uint32 PpapiCommandBufferProxy::InsertFutureSyncPoint() {
190 uint32 sync_point = 0;
191 if (last_state_.error == gpu::error::kNoError) {
192 Send(new PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint(
193 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, &sync_point));
195 return sync_point;
198 void PpapiCommandBufferProxy::RetireSyncPoint(uint32 sync_point) {
199 if (last_state_.error == gpu::error::kNoError) {
200 Send(new PpapiHostMsg_PPBGraphics3D_RetireSyncPoint(
201 ppapi::API_ID_PPB_GRAPHICS_3D, resource_, sync_point));
205 void PpapiCommandBufferProxy::SignalSyncPoint(uint32 sync_point,
206 const base::Closure& callback) {
207 NOTREACHED();
210 void PpapiCommandBufferProxy::SignalQuery(uint32 query,
211 const base::Closure& callback) {
212 NOTREACHED();
215 void PpapiCommandBufferProxy::SetSurfaceVisible(bool visible) {
216 NOTREACHED();
219 gpu::Capabilities PpapiCommandBufferProxy::GetCapabilities() {
220 return capabilities_;
223 int32 PpapiCommandBufferProxy::CreateImage(ClientBuffer buffer,
224 size_t width,
225 size_t height,
226 unsigned internalformat) {
227 NOTREACHED();
228 return -1;
231 void PpapiCommandBufferProxy::DestroyImage(int32 id) {
232 NOTREACHED();
235 int32 PpapiCommandBufferProxy::CreateGpuMemoryBufferImage(
236 size_t width,
237 size_t height,
238 unsigned internalformat,
239 unsigned usage) {
240 NOTREACHED();
241 return -1;
244 bool PpapiCommandBufferProxy::Send(IPC::Message* msg) {
245 DCHECK(last_state_.error == gpu::error::kNoError);
247 // We need to hold the Pepper proxy lock for sync IPC, because the GPU command
248 // buffer may use a sync IPC with another lock held which could lead to lock
249 // and deadlock if we dropped the proxy lock here.
250 // http://crbug.com/418651
251 if (dispatcher_->SendAndStayLocked(msg))
252 return true;
254 last_state_.error = gpu::error::kLostContext;
255 return false;
258 void PpapiCommandBufferProxy::UpdateState(
259 const gpu::CommandBuffer::State& state,
260 bool success) {
261 // Handle wraparound. It works as long as we don't have more than 2B state
262 // updates in flight across which reordering occurs.
263 if (success) {
264 if (state.generation - last_state_.generation < 0x80000000U) {
265 last_state_ = state;
267 } else {
268 last_state_.error = gpu::error::kLostContext;
269 ++last_state_.generation;
273 void PpapiCommandBufferProxy::TryUpdateState() {
274 if (last_state_.error == gpu::error::kNoError)
275 shared_state()->Read(&last_state_);
278 gpu::CommandBufferSharedState* PpapiCommandBufferProxy::shared_state() const {
279 return reinterpret_cast<gpu::CommandBufferSharedState*>(
280 shared_state_shm_->memory());
283 void PpapiCommandBufferProxy::FlushInternal() {
284 DCHECK(last_state_.error == gpu::error::kNoError);
286 DCHECK(flush_info_->flush_pending);
288 IPC::Message* message = new PpapiHostMsg_PPBGraphics3D_AsyncFlush(
289 ppapi::API_ID_PPB_GRAPHICS_3D, flush_info_->resource,
290 flush_info_->put_offset);
292 // Do not let a synchronous flush hold up this message. If this handler is
293 // deferred until after the synchronous flush completes, it will overwrite the
294 // cached last_state_ with out-of-date data.
295 message->set_unblock(true);
296 Send(message);
298 flush_info_->flush_pending = false;
299 flush_info_->resource.SetHostResource(0, 0);
302 } // namespace proxy
303 } // namespace ppapi