blob: b5a2dee95a42829371f07721959ab4664bc5bfe2 [file] [log] [blame]
[email protected]eeb4e4a2011-07-19 16:22:061// 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
3// found in the LICENSE file.
4
5#include "ppapi/proxy/ppb_graphics_3d_proxy.h"
6
7#include "gpu/command_buffer/client/gles2_implementation.h"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/proxy/enter_proxy.h"
10#include "ppapi/proxy/plugin_dispatcher.h"
11#include "ppapi/proxy/ppapi_messages.h"
12#include "ppapi/thunk/enter.h"
13#include "ppapi/thunk/resource_creation_api.h"
14#include "ppapi/thunk/thunk.h"
15
16using ppapi::thunk::EnterFunctionNoLock;
17using ppapi::thunk::EnterResourceNoLock;
18using ppapi::thunk::PPB_Graphics3D_API;
19using ppapi::thunk::ResourceCreationAPI;
20
[email protected]4d2efd22011-08-18 21:58:0221namespace ppapi {
[email protected]eeb4e4a2011-07-19 16:22:0622namespace proxy {
23
24namespace {
25const int32 kCommandBufferSize = 1024 * 1024;
26const int32 kTransferBufferSize = 1024 * 1024;
27
28class CommandBuffer : public gpu::CommandBuffer {
29 public:
30 CommandBuffer(const HostResource& resource, PluginDispatcher* dispatcher);
31 virtual ~CommandBuffer();
32
33 // gpu::CommandBuffer implementation:
[email protected]503b3a22011-12-12 23:29:4034 virtual bool Initialize();
[email protected]eeb4e4a2011-07-19 16:22:0635 virtual State GetState();
[email protected]d58730d2011-07-26 00:00:4136 virtual State GetLastState();
[email protected]eeb4e4a2011-07-19 16:22:0637 virtual void Flush(int32 put_offset);
38 virtual State FlushSync(int32 put_offset, int32 last_known_get);
[email protected]503b3a22011-12-12 23:29:4039 virtual void SetGetBuffer(int32 transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:0640 virtual void SetGetOffset(int32 get_offset);
41 virtual int32 CreateTransferBuffer(size_t size, int32 id_request);
42 virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
43 size_t size,
44 int32 id_request);
45 virtual void DestroyTransferBuffer(int32 id);
46 virtual gpu::Buffer GetTransferBuffer(int32 handle);
47 virtual void SetToken(int32 token);
48 virtual void SetParseError(gpu::error::Error error);
49 virtual void SetContextLostReason(gpu::error::ContextLostReason reason);
50
51 private:
52 bool Send(IPC::Message* msg);
53 void UpdateState(const gpu::CommandBuffer::State& state);
54
[email protected]eeb4e4a2011-07-19 16:22:0655 typedef base::hash_map<int32, gpu::Buffer> TransferBufferMap;
56 TransferBufferMap transfer_buffers_;
57
58 State last_state_;
59
60 HostResource resource_;
61 PluginDispatcher* dispatcher_;
62
63 DISALLOW_COPY_AND_ASSIGN(CommandBuffer);
64};
65
66CommandBuffer::CommandBuffer(const HostResource& resource,
67 PluginDispatcher* dispatcher)
[email protected]503b3a22011-12-12 23:29:4068 : resource_(resource),
[email protected]eeb4e4a2011-07-19 16:22:0669 dispatcher_(dispatcher) {
70}
71
72CommandBuffer::~CommandBuffer() {
73 // Delete all the locally cached shared memory objects, closing the handle
74 // in this process.
75 for (TransferBufferMap::iterator it = transfer_buffers_.begin();
76 it != transfer_buffers_.end(); ++it) {
77 delete it->second.shared_memory;
78 it->second.shared_memory = NULL;
79 }
80}
81
[email protected]503b3a22011-12-12 23:29:4082bool CommandBuffer::Initialize() {
83 return Send(new PpapiHostMsg_PPBGraphics3D_InitCommandBuffer(
84 API_ID_PPB_GRAPHICS_3D, resource_));
[email protected]eeb4e4a2011-07-19 16:22:0685}
86
87gpu::CommandBuffer::State CommandBuffer::GetState() {
88 // Send will flag state with lost context if IPC fails.
89 if (last_state_.error == gpu::error::kNoError) {
90 gpu::CommandBuffer::State state;
91 if (Send(new PpapiHostMsg_PPBGraphics3D_GetState(
[email protected]ac4b54d2011-10-20 23:09:2892 API_ID_PPB_GRAPHICS_3D, resource_, &state)))
[email protected]eeb4e4a2011-07-19 16:22:0693 UpdateState(state);
94 }
95
96 return last_state_;
97}
98
[email protected]d58730d2011-07-26 00:00:4199gpu::CommandBuffer::State CommandBuffer::GetLastState() {
100 return last_state_;
101}
102
[email protected]eeb4e4a2011-07-19 16:22:06103void CommandBuffer::Flush(int32 put_offset) {
104 if (last_state_.error != gpu::error::kNoError)
105 return;
106
107 IPC::Message* message = new PpapiHostMsg_PPBGraphics3D_AsyncFlush(
[email protected]ac4b54d2011-10-20 23:09:28108 API_ID_PPB_GRAPHICS_3D, resource_, put_offset);
[email protected]eeb4e4a2011-07-19 16:22:06109
110 // Do not let a synchronous flush hold up this message. If this handler is
111 // deferred until after the synchronous flush completes, it will overwrite the
112 // cached last_state_ with out-of-date data.
113 message->set_unblock(true);
114 Send(message);
115}
116
117gpu::CommandBuffer::State CommandBuffer::FlushSync(int32 put_offset,
118 int32 last_known_get) {
119 if (last_known_get == last_state_.get_offset) {
120 // Send will flag state with lost context if IPC fails.
121 if (last_state_.error == gpu::error::kNoError) {
122 gpu::CommandBuffer::State state;
123 if (Send(new PpapiHostMsg_PPBGraphics3D_Flush(
[email protected]ac4b54d2011-10-20 23:09:28124 API_ID_PPB_GRAPHICS_3D, resource_, put_offset,
[email protected]eeb4e4a2011-07-19 16:22:06125 last_known_get, &state)))
126 UpdateState(state);
127 }
128 } else {
129 Flush(put_offset);
130 }
131
132 return last_state_;
133}
134
[email protected]503b3a22011-12-12 23:29:40135void CommandBuffer::SetGetBuffer(int32 transfer_buffer_id) {
136 if (last_state_.error == gpu::error::kNoError) {
137 Send(new PpapiHostMsg_PPBGraphics3D_SetGetBuffer(
138 API_ID_PPB_GRAPHICS_3D, resource_, transfer_buffer_id));
139 }
140}
141
[email protected]eeb4e4a2011-07-19 16:22:06142void CommandBuffer::SetGetOffset(int32 get_offset) {
143 // Not implemented in proxy.
144 NOTREACHED();
145}
146
147int32 CommandBuffer::CreateTransferBuffer(size_t size, int32 id_request) {
148 if (last_state_.error == gpu::error::kNoError) {
149 int32 id;
150 if (Send(new PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer(
[email protected]ac4b54d2011-10-20 23:09:28151 API_ID_PPB_GRAPHICS_3D, resource_, size, &id))) {
[email protected]eeb4e4a2011-07-19 16:22:06152 return id;
153 }
154 }
155
156 return -1;
157}
158
159int32 CommandBuffer::RegisterTransferBuffer(
160 base::SharedMemory* shared_memory,
161 size_t size,
162 int32 id_request) {
163 // Not implemented in proxy.
164 NOTREACHED();
165 return -1;
166}
167
168void CommandBuffer::DestroyTransferBuffer(int32 id) {
169 if (last_state_.error != gpu::error::kNoError)
170 return;
171
172 // Remove the transfer buffer from the client side4 cache.
173 TransferBufferMap::iterator it = transfer_buffers_.find(id);
174 DCHECK(it != transfer_buffers_.end());
175
176 // Delete the shared memory object, closing the handle in this process.
177 delete it->second.shared_memory;
178
179 transfer_buffers_.erase(it);
180
181 Send(new PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer(
[email protected]ac4b54d2011-10-20 23:09:28182 API_ID_PPB_GRAPHICS_3D, resource_, id));
[email protected]eeb4e4a2011-07-19 16:22:06183}
184
185gpu::Buffer CommandBuffer::GetTransferBuffer(int32 id) {
186 if (last_state_.error != gpu::error::kNoError)
187 return gpu::Buffer();
188
189 // Check local cache to see if there is already a client side shared memory
190 // object for this id.
191 TransferBufferMap::iterator it = transfer_buffers_.find(id);
192 if (it != transfer_buffers_.end()) {
193 return it->second;
194 }
195
196 // Assuming we are in the renderer process, the service is responsible for
197 // duplicating the handle. This might not be true for NaCl.
198 base::SharedMemoryHandle handle;
199 uint32 size;
200 if (!Send(new PpapiHostMsg_PPBGraphics3D_GetTransferBuffer(
[email protected]ac4b54d2011-10-20 23:09:28201 API_ID_PPB_GRAPHICS_3D, resource_, id, &handle, &size))) {
[email protected]eeb4e4a2011-07-19 16:22:06202 return gpu::Buffer();
203 }
204
205 // Cache the transfer buffer shared memory object client side.
206 scoped_ptr<base::SharedMemory> shared_memory(
207 new base::SharedMemory(handle, false));
208
209 // Map the shared memory on demand.
210 if (!shared_memory->memory()) {
211 if (!shared_memory->Map(size)) {
212 return gpu::Buffer();
213 }
214 }
215
216 gpu::Buffer buffer;
217 buffer.ptr = shared_memory->memory();
218 buffer.size = size;
219 buffer.shared_memory = shared_memory.release();
220 transfer_buffers_[id] = buffer;
221
222 return buffer;
223}
224
225void CommandBuffer::SetToken(int32 token) {
226 NOTREACHED();
227}
228
229void CommandBuffer::SetParseError(gpu::error::Error error) {
230 NOTREACHED();
231}
232
233void CommandBuffer::SetContextLostReason(
234 gpu::error::ContextLostReason reason) {
235 NOTREACHED();
236}
237
238bool CommandBuffer::Send(IPC::Message* msg) {
239 DCHECK(last_state_.error == gpu::error::kNoError);
240
241 if (dispatcher_->Send(msg))
242 return true;
243
244 last_state_.error = gpu::error::kLostContext;
245 return false;
246}
247
248void CommandBuffer::UpdateState(const gpu::CommandBuffer::State& state) {
249 // Handle wraparound. It works as long as we don't have more than 2B state
250 // updates in flight across which reordering occurs.
251 if (state.generation - last_state_.generation < 0x80000000U)
252 last_state_ = state;
253}
254
255base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
256 int shm_handle) {
257 // TODO(piman): Change trusted interface to return a PP_FileHandle, those
258 // casts are ugly.
259 base::PlatformFile source =
260#if defined(OS_WIN)
261 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shm_handle));
262#elif defined(OS_POSIX)
263 shm_handle;
264#else
265 #error Not implemented.
266#endif
267 // Don't close the handle, it doesn't belong to us.
268 return dispatcher->ShareHandleWithRemote(source, false);
269}
270
271PP_Graphics3DTrustedState GetErrorState() {
272 PP_Graphics3DTrustedState error_state = { 0 };
273 error_state.error = PPB_GRAPHICS3D_TRUSTED_ERROR_GENERICERROR;
274 return error_state;
275}
276
277gpu::CommandBuffer::State GPUStateFromPPState(
278 const PP_Graphics3DTrustedState& s) {
279 gpu::CommandBuffer::State state;
280 state.num_entries = s.num_entries;
281 state.get_offset = s.get_offset;
282 state.put_offset = s.put_offset;
283 state.token = s.token;
284 state.error = static_cast<gpu::error::Error>(s.error);
285 state.generation = s.generation;
286 return state;
287}
288
[email protected]eeb4e4a2011-07-19 16:22:06289} // namespace
290
291Graphics3D::Graphics3D(const HostResource& resource)
[email protected]7f8b26b2011-08-18 15:41:01292 : Resource(resource) {
[email protected]eeb4e4a2011-07-19 16:22:06293}
294
295Graphics3D::~Graphics3D() {
296 DestroyGLES2Impl();
297}
298
299bool Graphics3D::Init() {
[email protected]7f8b26b2011-08-18 15:41:01300 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:06301 if (!dispatcher)
302 return false;
303
304 command_buffer_.reset(new CommandBuffer(host_resource(), dispatcher));
[email protected]503b3a22011-12-12 23:29:40305 if (!command_buffer_->Initialize())
[email protected]0e50fc4d2011-08-01 15:33:51306 return false;
[email protected]eeb4e4a2011-07-19 16:22:06307
308 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize);
309}
310
[email protected]503b3a22011-12-12 23:29:40311PP_Bool Graphics3D::InitCommandBuffer() {
[email protected]eeb4e4a2011-07-19 16:22:06312 return PP_FALSE;
313}
314
[email protected]503b3a22011-12-12 23:29:40315PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:06316 return PP_FALSE;
317}
318
319PP_Graphics3DTrustedState Graphics3D::GetState() {
320 return GetErrorState();
321}
322
323PP_Bool Graphics3D::Flush(int32_t put_offset) {
324 return PP_FALSE;
325}
326
327PP_Graphics3DTrustedState Graphics3D::FlushSync(int32_t put_offset) {
328 return GetErrorState();
329}
330
331int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
332 return PP_FALSE;
333}
334
335PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
336 return PP_FALSE;
337}
338
339PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
340 int* shm_handle,
341 uint32_t* shm_size) {
342 return PP_FALSE;
343}
344
345PP_Graphics3DTrustedState Graphics3D::FlushSyncFast(int32_t put_offset,
346 int32_t last_known_get) {
347 return GetErrorState();
348}
349
350gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
351 return command_buffer_.get();
352}
353
354int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23355 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06356 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28357 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06358 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01359 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06360
[email protected]eeb4e4a2011-07-19 16:22:06361 return PP_OK_COMPLETIONPENDING;
362}
363
[email protected]5c966022011-09-13 18:09:37364PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
365 : InterfaceProxy(dispatcher),
[email protected]0e50fc4d2011-08-01 15:33:51366 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
[email protected]eeb4e4a2011-07-19 16:22:06367}
368
369PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
370}
371
372// static
[email protected]eeb4e4a2011-07-19 16:22:06373PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
374 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06375 PP_Resource share_context,
376 const int32_t* attrib_list) {
377 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
378 if (!dispatcher)
379 return PP_ERROR_BADARGUMENT;
380
381 // TODO(alokp): Support shared context.
382 DCHECK_EQ(0, share_context);
383 if (share_context != 0)
384 return 0;
385
386 std::vector<int32_t> attribs;
387 if (attrib_list) {
388 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51389 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
390 attr += 2) {
391 attribs.push_back(attr[0]);
392 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06393 }
[email protected]eeb4e4a2011-07-19 16:22:06394 }
[email protected]0e50fc4d2011-08-01 15:33:51395 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06396
397 HostResource result;
398 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]ac4b54d2011-10-20 23:09:28399 API_ID_PPB_GRAPHICS_3D, instance, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06400 if (result.is_null())
401 return 0;
402
[email protected]51e1aec2011-08-11 04:48:30403 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]eeb4e4a2011-07-19 16:22:06404 if (!graphics_3d->Init())
405 return 0;
[email protected]7f8b26b2011-08-18 15:41:01406 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06407}
408
409bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
410 bool handled = true;
411 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
412 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
413 OnMsgCreate)
414 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer,
415 OnMsgInitCommandBuffer)
[email protected]503b3a22011-12-12 23:29:40416 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
417 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06418 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
419 OnMsgGetState)
420 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush,
421 OnMsgFlush)
422 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush,
423 OnMsgAsyncFlush)
424 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
425 OnMsgCreateTransferBuffer)
426 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
427 OnMsgDestroyTransferBuffer)
428 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
429 OnMsgGetTransferBuffer)
430 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
431 OnMsgSwapBuffers)
432
433 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
434 OnMsgSwapBuffersACK)
435 IPC_MESSAGE_UNHANDLED(handled = false)
436
437 IPC_END_MESSAGE_MAP()
438 // FIXME(brettw) handle bad messages!
439 return handled;
440}
441
442void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06443 const std::vector<int32_t>& attribs,
444 HostResource* result) {
[email protected]0e50fc4d2011-08-01 15:33:51445 if (attribs.empty() || attribs.back() != PP_GRAPHICS3DATTRIB_NONE)
[email protected]eeb4e4a2011-07-19 16:22:06446 return; // Bad message.
447
[email protected]5c966022011-09-13 18:09:37448 thunk::EnterResourceCreation enter(instance);
[email protected]eeb4e4a2011-07-19 16:22:06449 if (enter.succeeded()) {
450 result->SetHostResource(
451 instance,
[email protected]9d8fe822011-08-16 21:02:52452 enter.functions()->CreateGraphics3DRaw(instance, 0, &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06453 }
454}
455
456void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer(
[email protected]503b3a22011-12-12 23:29:40457 const HostResource& context) {
[email protected]eeb4e4a2011-07-19 16:22:06458 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
459 if (enter.failed())
460 return;
461
[email protected]503b3a22011-12-12 23:29:40462 if (!enter.object()->InitCommandBuffer())
[email protected]eeb4e4a2011-07-19 16:22:06463 return;
[email protected]503b3a22011-12-12 23:29:40464}
[email protected]eeb4e4a2011-07-19 16:22:06465
[email protected]503b3a22011-12-12 23:29:40466void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
467 const HostResource& context,
468 int32 transfer_buffer_id) {
469 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
470 if (enter.succeeded())
471 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06472}
473
474void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
475 gpu::CommandBuffer::State* state) {
476 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
477 if (enter.failed())
478 return;
479 PP_Graphics3DTrustedState pp_state = enter.object()->GetState();
480 *state = GPUStateFromPPState(pp_state);
481}
482
483void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
484 int32 put_offset,
485 int32 last_known_get,
486 gpu::CommandBuffer::State* state) {
487 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
488 if (enter.failed())
489 return;
490 PP_Graphics3DTrustedState pp_state = enter.object()->FlushSyncFast(
491 put_offset, last_known_get);
492 *state = GPUStateFromPPState(pp_state);
493}
494
495void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
496 int32 put_offset) {
497 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
498 if (enter.succeeded())
499 enter.object()->Flush(put_offset);
500}
501
502void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
503 const HostResource& context,
504 int32 size,
505 int32* id) {
506 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
507 if (enter.succeeded())
508 *id = enter.object()->CreateTransferBuffer(size);
509 else
510 *id = 0;
511}
512
513void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
514 const HostResource& context,
515 int32 id) {
516 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
517 if (enter.succeeded())
518 enter.object()->DestroyTransferBuffer(id);
519}
520
521void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
522 const HostResource& context,
523 int32 id,
524 base::SharedMemoryHandle* transfer_buffer,
525 uint32* size) {
526 *transfer_buffer = base::SharedMemory::NULLHandle();
527 *size = 0;
528
529 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
530 int shm_handle = 0;
531 uint32_t shm_size = 0;
532 if (enter.succeeded() &&
533 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
534 *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
535 *size = shm_size;
536 }
537}
538
539void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40540 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
541 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06542 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06543 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40544 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06545}
546
547void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
548 int32_t pp_error) {
549 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
550 if (enter.succeeded())
551 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
552}
553
554void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
555 int32_t result,
556 const HostResource& context) {
557 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28558 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06559}
560
561} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02562} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06563