blob: 9d2ecd66a0687d19b0ffee56eacf3482fa5c64ea [file] [log] [blame]
[email protected]aaa11b32012-03-08 12:30:131// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]eeb4e4a2011-07-19 16:22:062// 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"
[email protected]84b44c552012-10-15 20:58:178#include "gpu/command_buffer/common/command_buffer.h"
[email protected]eeb4e4a2011-07-19 16:22:069#include "ppapi/c/pp_errors.h"
10#include "ppapi/proxy/enter_proxy.h"
11#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]aaa11b32012-03-08 12:30:1312#include "ppapi/proxy/ppapi_command_buffer_proxy.h"
[email protected]eeb4e4a2011-07-19 16:22:0613#include "ppapi/proxy/ppapi_messages.h"
[email protected]84b44c552012-10-15 20:58:1714#include "ppapi/shared_impl/ppapi_globals.h"
15#include "ppapi/shared_impl/proxy_lock.h"
[email protected]eeb4e4a2011-07-19 16:22:0616#include "ppapi/thunk/enter.h"
17#include "ppapi/thunk/resource_creation_api.h"
18#include "ppapi/thunk/thunk.h"
19
[email protected]eeb4e4a2011-07-19 16:22:0620using ppapi::thunk::EnterResourceNoLock;
21using ppapi::thunk::PPB_Graphics3D_API;
22using ppapi::thunk::ResourceCreationAPI;
23
[email protected]4d2efd22011-08-18 21:58:0224namespace ppapi {
[email protected]eeb4e4a2011-07-19 16:22:0625namespace proxy {
26
27namespace {
[email protected]84b44c552012-10-15 20:58:1728
[email protected]eeb4e4a2011-07-19 16:22:0629const int32 kCommandBufferSize = 1024 * 1024;
30const int32 kTransferBufferSize = 1024 * 1024;
31
[email protected]eeb4e4a2011-07-19 16:22:0632base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
33 int shm_handle) {
34 // TODO(piman): Change trusted interface to return a PP_FileHandle, those
35 // casts are ugly.
36 base::PlatformFile source =
37#if defined(OS_WIN)
38 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shm_handle));
39#elif defined(OS_POSIX)
40 shm_handle;
41#else
42 #error Not implemented.
43#endif
44 // Don't close the handle, it doesn't belong to us.
45 return dispatcher->ShareHandleWithRemote(source, false);
46}
47
48PP_Graphics3DTrustedState GetErrorState() {
49 PP_Graphics3DTrustedState error_state = { 0 };
50 error_state.error = PPB_GRAPHICS3D_TRUSTED_ERROR_GENERICERROR;
51 return error_state;
52}
53
54gpu::CommandBuffer::State GPUStateFromPPState(
55 const PP_Graphics3DTrustedState& s) {
56 gpu::CommandBuffer::State state;
57 state.num_entries = s.num_entries;
58 state.get_offset = s.get_offset;
59 state.put_offset = s.put_offset;
60 state.token = s.token;
61 state.error = static_cast<gpu::error::Error>(s.error);
62 state.generation = s.generation;
63 return state;
64}
65
[email protected]eeb4e4a2011-07-19 16:22:0666} // namespace
67
[email protected]84b44c552012-10-15 20:58:1768// This class just wraps a CommandBuffer and optionally locks around every
69// method. This is used to ensure that we have the Proxy lock any time we enter
70// PpapiCommandBufferProxy.
71//
72// Note, for performance reasons, most of this code is not truly thread
73// safe in the sense of multiple threads concurrently rendering to the same
74// Graphics3D context; this isn't allowed, and will likely either crash or
75// result in undefined behavior. It is assumed that the thread which creates
76// the Graphics3D context will be the thread on which subsequent gl rendering
77// will be done.
78//
79// TODO(nfullagar): At some point, allow multiple threads to concurrently render
80// each to its own context. First step is to allow a single thread (either main
81// thread or background thread) to render to a single Graphics3D context.
82class Graphics3D::LockingCommandBuffer : public gpu::CommandBuffer {
83 public:
84 explicit LockingCommandBuffer(gpu::CommandBuffer* gpu_command_buffer)
85 : gpu_command_buffer_(gpu_command_buffer), need_to_lock_(true) {
86 }
87 virtual ~LockingCommandBuffer() {
88 }
89 void set_need_to_lock(bool need_to_lock) { need_to_lock_ = need_to_lock; }
90 bool need_to_lock() const { return need_to_lock_; }
91
92 private:
93 // MaybeLock acquires the proxy lock on construction if and only if
94 // need_to_lock is true. If it acquired the lock, it releases it on
95 // destruction. If need_to_lock is false, then the lock must already be held.
96 struct MaybeLock {
97 explicit MaybeLock(bool need_to_lock) : locked_(need_to_lock) {
98 if (need_to_lock)
99 ppapi::ProxyLock::Acquire();
100 else
101 ppapi::ProxyLock::AssertAcquired();
102 }
103 ~MaybeLock() {
104 if (locked_)
105 ppapi::ProxyLock::Release();
106 }
107 private:
108 bool locked_;
109 };
110
111 // gpu::CommandBuffer implementation:
112 virtual bool Initialize() OVERRIDE {
113 MaybeLock lock(need_to_lock_);
114 return gpu_command_buffer_->Initialize();
115 }
116 virtual State GetState() OVERRIDE {
117 MaybeLock lock(need_to_lock_);
118 return gpu_command_buffer_->GetState();
119 }
120 virtual State GetLastState() OVERRIDE {
121 // During a normal scene, the vast majority of calls are to GetLastState().
122 // We don't allow multi-threaded rendering on the same contex, so for
123 // performance reasons, avoid the global lock for this entry point. We can
124 // get away with this here because the underlying implementation of
125 // GetLastState() is trivial and does not involve global or shared state
126 // between other contexts.
127 // TODO(nfullagar): We can probably skip MaybeLock for other methods, but
128 // the performance gain may not be worth it.
129 //
130 // MaybeLock lock(need_to_lock_);
131 return gpu_command_buffer_->GetLastState();
132 }
133 virtual void Flush(int32 put_offset) OVERRIDE {
134 MaybeLock lock(need_to_lock_);
135 gpu_command_buffer_->Flush(put_offset);
136 }
137 virtual State FlushSync(int32 put_offset, int32 last_known_get) OVERRIDE {
138 MaybeLock lock(need_to_lock_);
139 return gpu_command_buffer_->FlushSync(put_offset, last_known_get);
140 }
141 virtual void SetGetBuffer(int32 transfer_buffer_id) OVERRIDE {
142 MaybeLock lock(need_to_lock_);
143 gpu_command_buffer_->SetGetBuffer(transfer_buffer_id);
144 }
145 virtual void SetGetOffset(int32 get_offset) OVERRIDE {
146 MaybeLock lock(need_to_lock_);
147 gpu_command_buffer_->SetGetOffset(get_offset);
148 }
149 virtual int32 CreateTransferBuffer(size_t size, int32 id_request) OVERRIDE {
150 MaybeLock lock(need_to_lock_);
151 return gpu_command_buffer_->CreateTransferBuffer(size, id_request);
152 }
153 virtual int32 RegisterTransferBuffer(base::SharedMemory* shared_memory,
154 size_t size,
155 int32 id_request) OVERRIDE {
156 MaybeLock lock(need_to_lock_);
157 return gpu_command_buffer_->RegisterTransferBuffer(shared_memory, size,
158 id_request);
159 }
160 virtual void DestroyTransferBuffer(int32 id) OVERRIDE {
161 MaybeLock lock(need_to_lock_);
162 gpu_command_buffer_->DestroyTransferBuffer(id);
163 }
164 virtual gpu::Buffer GetTransferBuffer(int32 handle) OVERRIDE {
165 MaybeLock lock(need_to_lock_);
166 return gpu_command_buffer_->GetTransferBuffer(handle);
167 }
168 virtual void SetToken(int32 token) OVERRIDE {
169 MaybeLock lock(need_to_lock_);
170 gpu_command_buffer_->SetToken(token);
171 }
172 virtual void SetParseError(gpu::error::Error error) OVERRIDE {
173 MaybeLock lock(need_to_lock_);
174 gpu_command_buffer_->SetParseError(error);
175 }
176 virtual void SetContextLostReason(
177 gpu::error::ContextLostReason reason) OVERRIDE {
178 MaybeLock lock(need_to_lock_);
179 gpu_command_buffer_->SetContextLostReason(reason);
180 }
181
182 // Weak pointer - see class Graphics3D for the scopted_ptr.
183 gpu::CommandBuffer* gpu_command_buffer_;
184
185 bool need_to_lock_;
186};
187
[email protected]eeb4e4a2011-07-19 16:22:06188Graphics3D::Graphics3D(const HostResource& resource)
[email protected]84b44c552012-10-15 20:58:17189 : PPB_Graphics3D_Shared(resource),
190 num_already_locked_calls_(0) {
[email protected]eeb4e4a2011-07-19 16:22:06191}
192
193Graphics3D::~Graphics3D() {
194 DestroyGLES2Impl();
195}
196
[email protected]9ed07f82012-05-29 21:54:55197bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
[email protected]7f8b26b2011-08-18 15:41:01198 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:06199 if (!dispatcher)
200 return false;
201
[email protected]aaa11b32012-03-08 12:30:13202 command_buffer_.reset(
203 new PpapiCommandBufferProxy(host_resource(), dispatcher));
[email protected]84b44c552012-10-15 20:58:17204 locking_command_buffer_.reset(
205 new LockingCommandBuffer(command_buffer_.get()));
206
207 ScopedNoLocking already_locked(this);
[email protected]503b3a22011-12-12 23:29:40208 if (!command_buffer_->Initialize())
[email protected]0e50fc4d2011-08-01 15:33:51209 return false;
[email protected]eeb4e4a2011-07-19 16:22:06210
[email protected]9ed07f82012-05-29 21:54:55211 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
212 share_gles2);
[email protected]eeb4e4a2011-07-19 16:22:06213}
214
[email protected]503b3a22011-12-12 23:29:40215PP_Bool Graphics3D::InitCommandBuffer() {
[email protected]eeb4e4a2011-07-19 16:22:06216 return PP_FALSE;
217}
218
[email protected]503b3a22011-12-12 23:29:40219PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:06220 return PP_FALSE;
221}
222
223PP_Graphics3DTrustedState Graphics3D::GetState() {
224 return GetErrorState();
225}
226
227PP_Bool Graphics3D::Flush(int32_t put_offset) {
228 return PP_FALSE;
229}
230
231PP_Graphics3DTrustedState Graphics3D::FlushSync(int32_t put_offset) {
232 return GetErrorState();
233}
234
235int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
236 return PP_FALSE;
237}
238
239PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
240 return PP_FALSE;
241}
242
243PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
244 int* shm_handle,
245 uint32_t* shm_size) {
246 return PP_FALSE;
247}
248
249PP_Graphics3DTrustedState Graphics3D::FlushSyncFast(int32_t put_offset,
250 int32_t last_known_get) {
251 return GetErrorState();
252}
253
254gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
[email protected]84b44c552012-10-15 20:58:17255 return locking_command_buffer_.get();
[email protected]eeb4e4a2011-07-19 16:22:06256}
257
258int32 Graphics3D::DoSwapBuffers() {
[email protected]84b44c552012-10-15 20:58:17259 // gles2_impl()->SwapBuffers() results in CommandBuffer calls, and we already
260 // have the proxy lock.
261 ScopedNoLocking already_locked(this);
262
[email protected]561438abd2011-11-24 01:06:23263 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06264 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28265 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06266 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01267 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06268
[email protected]eeb4e4a2011-07-19 16:22:06269 return PP_OK_COMPLETIONPENDING;
270}
271
[email protected]84b44c552012-10-15 20:58:17272void Graphics3D::PushAlreadyLocked() {
273 ppapi::ProxyLock::AssertAcquired();
274 if (num_already_locked_calls_ == 0)
275 locking_command_buffer_->set_need_to_lock(false);
276 ++num_already_locked_calls_;
277}
278
279void Graphics3D::PopAlreadyLocked() {
280 // We must have Pushed before we can Pop.
281 DCHECK(!locking_command_buffer_->need_to_lock());
282 DCHECK_GT(num_already_locked_calls_, 0);
283 ppapi::ProxyLock::AssertAcquired();
284 --num_already_locked_calls_;
285 if (num_already_locked_calls_ == 0)
286 locking_command_buffer_->set_need_to_lock(true);
287}
288
[email protected]5c966022011-09-13 18:09:37289PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
290 : InterfaceProxy(dispatcher),
[email protected]0e50fc4d2011-08-01 15:33:51291 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
[email protected]eeb4e4a2011-07-19 16:22:06292}
293
294PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
295}
296
297// static
[email protected]eeb4e4a2011-07-19 16:22:06298PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
299 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06300 PP_Resource share_context,
301 const int32_t* attrib_list) {
302 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
303 if (!dispatcher)
304 return PP_ERROR_BADARGUMENT;
305
[email protected]9ed07f82012-05-29 21:54:55306 HostResource share_host;
307 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
308 if (share_context != 0) {
309 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
310 if (enter.failed())
311 return PP_ERROR_BADARGUMENT;
312
313 PPB_Graphics3D_Shared* share_graphics =
314 static_cast<PPB_Graphics3D_Shared*>(enter.object());
315 share_host = share_graphics->host_resource();
316 share_gles2 = share_graphics->gles2_impl();
317 }
[email protected]eeb4e4a2011-07-19 16:22:06318
319 std::vector<int32_t> attribs;
320 if (attrib_list) {
321 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51322 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
323 attr += 2) {
324 attribs.push_back(attr[0]);
325 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06326 }
[email protected]eeb4e4a2011-07-19 16:22:06327 }
[email protected]0e50fc4d2011-08-01 15:33:51328 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06329
330 HostResource result;
331 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]9ed07f82012-05-29 21:54:55332 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06333 if (result.is_null())
334 return 0;
335
[email protected]51e1aec2011-08-11 04:48:30336 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]9ed07f82012-05-29 21:54:55337 if (!graphics_3d->Init(share_gles2))
[email protected]eeb4e4a2011-07-19 16:22:06338 return 0;
[email protected]7f8b26b2011-08-18 15:41:01339 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06340}
341
342bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
343 bool handled = true;
344 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
345 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
346 OnMsgCreate)
347 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer,
348 OnMsgInitCommandBuffer)
[email protected]503b3a22011-12-12 23:29:40349 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
350 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06351 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
352 OnMsgGetState)
353 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush,
354 OnMsgFlush)
355 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush,
356 OnMsgAsyncFlush)
357 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
358 OnMsgCreateTransferBuffer)
359 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
360 OnMsgDestroyTransferBuffer)
361 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
362 OnMsgGetTransferBuffer)
363 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
364 OnMsgSwapBuffers)
365
366 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
367 OnMsgSwapBuffersACK)
368 IPC_MESSAGE_UNHANDLED(handled = false)
369
370 IPC_END_MESSAGE_MAP()
371 // FIXME(brettw) handle bad messages!
372 return handled;
373}
374
375void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]9ed07f82012-05-29 21:54:55376 HostResource share_context,
[email protected]eeb4e4a2011-07-19 16:22:06377 const std::vector<int32_t>& attribs,
378 HostResource* result) {
[email protected]0e50fc4d2011-08-01 15:33:51379 if (attribs.empty() || attribs.back() != PP_GRAPHICS3DATTRIB_NONE)
[email protected]eeb4e4a2011-07-19 16:22:06380 return; // Bad message.
381
[email protected]5c966022011-09-13 18:09:37382 thunk::EnterResourceCreation enter(instance);
[email protected]9ed07f82012-05-29 21:54:55383
[email protected]eeb4e4a2011-07-19 16:22:06384 if (enter.succeeded()) {
385 result->SetHostResource(
[email protected]9ed07f82012-05-29 21:54:55386 instance,
387 enter.functions()->CreateGraphics3DRaw(instance,
388 share_context.host_resource(),
389 &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06390 }
391}
392
393void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer(
[email protected]503b3a22011-12-12 23:29:40394 const HostResource& context) {
[email protected]eeb4e4a2011-07-19 16:22:06395 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
396 if (enter.failed())
397 return;
398
[email protected]503b3a22011-12-12 23:29:40399 if (!enter.object()->InitCommandBuffer())
[email protected]eeb4e4a2011-07-19 16:22:06400 return;
[email protected]503b3a22011-12-12 23:29:40401}
[email protected]eeb4e4a2011-07-19 16:22:06402
[email protected]503b3a22011-12-12 23:29:40403void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
404 const HostResource& context,
405 int32 transfer_buffer_id) {
406 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
407 if (enter.succeeded())
408 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06409}
410
411void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
[email protected]571b35e82012-05-19 00:04:35412 gpu::CommandBuffer::State* state,
413 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06414 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35415 if (enter.failed()) {
416 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06417 return;
[email protected]571b35e82012-05-19 00:04:35418 }
[email protected]eeb4e4a2011-07-19 16:22:06419 PP_Graphics3DTrustedState pp_state = enter.object()->GetState();
420 *state = GPUStateFromPPState(pp_state);
[email protected]571b35e82012-05-19 00:04:35421 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06422}
423
424void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
425 int32 put_offset,
426 int32 last_known_get,
[email protected]571b35e82012-05-19 00:04:35427 gpu::CommandBuffer::State* state,
428 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06429 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35430 if (enter.failed()) {
431 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06432 return;
[email protected]571b35e82012-05-19 00:04:35433 }
[email protected]eeb4e4a2011-07-19 16:22:06434 PP_Graphics3DTrustedState pp_state = enter.object()->FlushSyncFast(
435 put_offset, last_known_get);
436 *state = GPUStateFromPPState(pp_state);
[email protected]571b35e82012-05-19 00:04:35437 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06438}
439
440void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
441 int32 put_offset) {
442 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
443 if (enter.succeeded())
444 enter.object()->Flush(put_offset);
445}
446
447void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
448 const HostResource& context,
449 int32 size,
450 int32* id) {
451 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
452 if (enter.succeeded())
453 *id = enter.object()->CreateTransferBuffer(size);
454 else
455 *id = 0;
456}
457
458void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
459 const HostResource& context,
460 int32 id) {
461 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
462 if (enter.succeeded())
463 enter.object()->DestroyTransferBuffer(id);
464}
465
466void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
467 const HostResource& context,
468 int32 id,
[email protected]246fc492012-08-27 20:28:18469 ppapi::proxy::SerializedHandle* transfer_buffer) {
470 transfer_buffer->set_null_shmem();
[email protected]eeb4e4a2011-07-19 16:22:06471
472 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
473 int shm_handle = 0;
474 uint32_t shm_size = 0;
475 if (enter.succeeded() &&
476 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
[email protected]246fc492012-08-27 20:28:18477 transfer_buffer->set_shmem(
478 TransportSHMHandleFromInt(dispatcher(), shm_handle),
479 shm_size);
[email protected]eeb4e4a2011-07-19 16:22:06480 }
481}
482
483void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40484 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
485 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06486 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06487 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40488 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06489}
490
491void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
492 int32_t pp_error) {
493 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
494 if (enter.succeeded())
495 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
496}
497
498void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
499 int32_t result,
500 const HostResource& context) {
501 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28502 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06503}
504
505} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02506} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06507