OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "ppapi/proxy/ppb_context_3d_proxy.h" | |
6 | |
7 #include "base/hash_tables.h" | |
8 #include "gpu/command_buffer/client/gles2_cmd_helper.h" | |
9 #include "gpu/command_buffer/client/gles2_implementation.h" | |
10 #include "ppapi/c/pp_errors.h" | |
11 #include "ppapi/c/pp_resource.h" | |
12 #include "ppapi/c/dev/ppb_context_3d_dev.h" | |
13 #include "ppapi/c/dev/ppb_context_3d_trusted_dev.h" | |
14 #include "ppapi/proxy/plugin_dispatcher.h" | |
15 #include "ppapi/proxy/plugin_resource.h" | |
16 #include "ppapi/proxy/ppapi_messages.h" | |
17 #include "ppapi/proxy/ppb_surface_3d_proxy.h" | |
18 | |
19 namespace pp { | |
20 namespace proxy { | |
21 | |
22 namespace { | |
23 | |
24 PP_Resource Create(PP_Instance instance, | |
25 PP_Config3D_Dev config, | |
26 PP_Resource share_context, | |
27 const int32_t* attrib_list) { | |
28 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
29 if (!dispatcher) | |
30 return PP_ERROR_BADARGUMENT; | |
31 | |
32 // TODO(alokp): Support shared context. | |
33 DCHECK_EQ(0, share_context); | |
34 if (share_context != 0) | |
35 return 0; | |
36 | |
37 std::vector<int32_t> attribs; | |
38 if (attrib_list) { | |
39 for (const int32_t* attr = attrib_list; attr; ++attr) | |
40 attribs.push_back(*attr); | |
41 } else { | |
42 attribs.push_back(0); | |
43 } | |
44 | |
45 HostResource result; | |
46 dispatcher->Send(new PpapiHostMsg_PPBContext3D_Create( | |
47 INTERFACE_ID_PPB_CONTEXT_3D, instance, config, attribs, &result)); | |
48 | |
49 if (result.is_null()) | |
50 return 0; | |
51 linked_ptr<Context3D> context_3d(new Context3D(result)); | |
52 if (!context_3d->CreateImplementation()) | |
53 return 0; | |
54 return PluginResourceTracker::GetInstance()->AddResource(context_3d); | |
55 } | |
56 | |
57 PP_Bool IsContext3D(PP_Resource resource) { | |
58 Context3D* object = PluginResource::GetAs<Context3D>(resource); | |
59 return BoolToPPBool(!!object); | |
60 } | |
61 | |
62 int32_t GetAttrib(PP_Resource context, | |
63 int32_t attribute, | |
64 int32_t* value) { | |
65 // TODO(alokp): Implement me. | |
66 return 0; | |
67 } | |
68 | |
69 int32_t BindSurfaces(PP_Resource context_id, | |
70 PP_Resource draw, | |
71 PP_Resource read) { | |
72 Context3D* object = PluginResource::GetAs<Context3D>(context_id); | |
73 if (!object) | |
74 return PP_ERROR_BADRESOURCE; | |
75 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( | |
76 object->instance()); | |
77 if (!dispatcher) | |
78 return PP_ERROR_FAILED; | |
79 | |
80 // TODO(alokp): Support separate draw-read surfaces. | |
81 DCHECK_EQ(draw, read); | |
82 if (draw != read) | |
83 return PP_GRAPHICS3DERROR_BAD_MATCH; | |
84 | |
85 Surface3D* draw_surface = PluginResource::GetAs<Surface3D>(draw); | |
86 Surface3D* read_surface = PluginResource::GetAs<Surface3D>(read); | |
87 if (draw && !draw_surface) | |
88 return PP_ERROR_BADRESOURCE; | |
89 if (read && !read_surface) | |
90 return PP_ERROR_BADRESOURCE; | |
91 HostResource host_draw = | |
92 draw_surface ? draw_surface->host_resource() : HostResource(); | |
93 HostResource host_read = | |
94 read_surface ? read_surface->host_resource() : HostResource(); | |
95 | |
96 int32_t result; | |
97 dispatcher->Send(new PpapiHostMsg_PPBContext3D_BindSurfaces( | |
98 INTERFACE_ID_PPB_CONTEXT_3D, | |
99 object->host_resource(), | |
100 host_draw, | |
101 host_read, | |
102 &result)); | |
103 | |
104 if (result == PP_OK) { | |
brettw
2011/01/31 18:51:29
No {} since you didn't use them elsewhere.
piman
2011/01/31 19:34:29
Done.
| |
105 object->BindSurfaces(draw_surface, read_surface); | |
106 } | |
107 return result; | |
108 } | |
109 | |
110 int32_t GetBoundSurfaces(PP_Resource context, | |
111 PP_Resource* draw, | |
112 PP_Resource* read) { | |
113 Context3D* object = PluginResource::GetAs<Context3D>(context); | |
114 if (!object) | |
115 return PP_ERROR_BADRESOURCE; | |
116 | |
117 Surface3D* draw_surface; | |
118 Surface3D* read_surface; | |
119 object->get_surfaces(&draw_surface, &read_surface); | |
120 | |
121 *draw = draw_surface ? draw_surface->resource() : 0; | |
122 *read = read_surface ? read_surface->resource() : 0; | |
123 return PP_OK; | |
124 } | |
125 | |
126 | |
127 const PPB_Context3D_Dev ppb_context_3d = { | |
128 &Create, | |
129 &IsContext3D, | |
130 &GetAttrib, | |
131 &BindSurfaces, | |
132 &GetBoundSurfaces, | |
133 }; | |
134 | |
135 base::SharedMemoryHandle SHMHandleFromInt(int shm_handle) { | |
136 #if defined(OS_POSIX) | |
137 return base::FileDescriptor(shm_handle, true); | |
138 #elif defined(OS_WIN) | |
139 return reinterpret_cast<HANDLE>(shm_handle); | |
140 #else | |
141 #error "Platform not supported." | |
142 #endif | |
143 } | |
144 | |
145 gpu::CommandBuffer::State GPUStateFromPPState( | |
146 const PP_Context3DTrustedState& s) { | |
147 gpu::CommandBuffer::State state; | |
148 state.num_entries = s.num_entries; | |
149 state.get_offset = s.get_offset; | |
150 state.put_offset = s.put_offset; | |
151 state.token = s.token; | |
152 state.error = static_cast<gpu::error::Error>(s.error); | |
153 return state; | |
154 } | |
155 | |
156 // Size of the transfer buffer. | |
157 const int32 kCommandBufferSize = 1024 * 1024; | |
158 const int32 kTransferBufferSize = 1024 * 1024; | |
159 | |
160 } // namespace | |
161 | |
162 class PepperCommandBuffer : public gpu::CommandBuffer { | |
163 public: | |
164 PepperCommandBuffer(const HostResource& resource, | |
165 PluginDispatcher* dispatcher); | |
166 virtual ~PepperCommandBuffer(); | |
167 | |
168 // CommandBuffer implementation: | |
169 virtual bool Initialize(int32 size); | |
170 virtual gpu::Buffer GetRingBuffer(); | |
171 virtual State GetState(); | |
172 virtual void Flush(int32 put_offset); | |
173 virtual State FlushSync(int32 put_offset); | |
174 virtual void SetGetOffset(int32 get_offset); | |
175 virtual int32 CreateTransferBuffer(size_t size); | |
176 virtual void DestroyTransferBuffer(int32 id); | |
177 virtual gpu::Buffer GetTransferBuffer(int32 handle); | |
178 virtual void SetToken(int32 token); | |
179 virtual void SetParseError(gpu::error::Error error); | |
180 | |
181 private: | |
182 bool Send(IPC::Message* msg); | |
183 | |
184 int32 num_entries_; | |
185 scoped_ptr<base::SharedMemory> ring_buffer_; | |
186 | |
187 typedef base::hash_map<int32, gpu::Buffer> TransferBufferMap; | |
188 TransferBufferMap transfer_buffers_; | |
189 | |
190 State last_state_; | |
191 | |
192 HostResource resource_; | |
193 PluginDispatcher* dispatcher_; | |
194 | |
195 DISALLOW_COPY_AND_ASSIGN(PepperCommandBuffer); | |
196 }; | |
197 | |
198 PepperCommandBuffer::PepperCommandBuffer( | |
199 const HostResource& resource, | |
200 PluginDispatcher* dispatcher) | |
201 : num_entries_(0), | |
202 resource_(resource), | |
203 dispatcher_(dispatcher) { | |
204 } | |
205 | |
206 PepperCommandBuffer::~PepperCommandBuffer() { | |
207 // Delete all the locally cached shared memory objects, closing the handle | |
208 // in this process. | |
209 for (TransferBufferMap::iterator it = transfer_buffers_.begin(); | |
210 it != transfer_buffers_.end(); | |
211 ++it) { | |
212 delete it->second.shared_memory; | |
213 it->second.shared_memory = NULL; | |
214 } | |
215 } | |
216 | |
217 bool PepperCommandBuffer::Initialize(int32 size) { | |
218 DCHECK(!ring_buffer_.get()); | |
219 | |
220 // Initialize the service. Assuming we are sandboxed, the GPU | |
221 // process is responsible for duplicating the handle. This might not be true | |
222 // for NaCl. | |
223 base::SharedMemoryHandle handle; | |
224 if (Send(new PpapiHostMsg_PPBContext3D_Initialize( | |
225 INTERFACE_ID_PPB_CONTEXT_3D, resource_, size, &handle)) && | |
226 base::SharedMemory::IsHandleValid(handle)) { | |
227 ring_buffer_.reset(new base::SharedMemory(handle, false)); | |
228 if (ring_buffer_->Map(size)) { | |
229 num_entries_ = size / sizeof(gpu::CommandBufferEntry); | |
230 return true; | |
231 } | |
232 | |
233 ring_buffer_.reset(); | |
234 } | |
235 | |
236 return false; | |
237 } | |
238 | |
239 gpu::Buffer PepperCommandBuffer::GetRingBuffer() { | |
240 // Return locally cached ring buffer. | |
241 gpu::Buffer buffer; | |
242 buffer.ptr = ring_buffer_->memory(); | |
243 buffer.size = num_entries_ * sizeof(gpu::CommandBufferEntry); | |
244 buffer.shared_memory = ring_buffer_.get(); | |
245 return buffer; | |
246 } | |
247 | |
248 gpu::CommandBuffer::State PepperCommandBuffer::GetState() { | |
249 // Send will flag state with lost context if IPC fails. | |
250 if (last_state_.error == gpu::error::kNoError) { | |
251 Send(new PpapiHostMsg_PPBContext3D_GetState( | |
252 INTERFACE_ID_PPB_CONTEXT_3D, resource_, &last_state_)); | |
253 } | |
254 | |
255 return last_state_; | |
256 } | |
257 | |
258 void PepperCommandBuffer::Flush(int32 put_offset) { | |
259 if (last_state_.error != gpu::error::kNoError) | |
260 return; | |
261 | |
262 IPC::Message* message = new PpapiHostMsg_PPBContext3D_AsyncFlush( | |
263 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset); | |
264 | |
265 // Do not let a synchronous flush hold up this message. If this handler is | |
266 // deferred until after the synchronous flush completes, it will overwrite the | |
267 // cached last_state_ with out-of-date data. | |
268 message->set_unblock(true); | |
269 Send(message); | |
270 } | |
271 | |
272 gpu::CommandBuffer::State PepperCommandBuffer::FlushSync(int32 put_offset) { | |
273 // Send will flag state with lost context if IPC fails. | |
274 if (last_state_.error == gpu::error::kNoError) { | |
275 Send(new PpapiHostMsg_PPBContext3D_Flush( | |
276 INTERFACE_ID_PPB_CONTEXT_3D, resource_, put_offset, &last_state_)); | |
277 } | |
278 | |
279 return last_state_; | |
280 } | |
281 | |
282 void PepperCommandBuffer::SetGetOffset(int32 get_offset) { | |
283 // Not implemented in proxy. | |
284 NOTREACHED(); | |
285 } | |
286 | |
287 int32 PepperCommandBuffer::CreateTransferBuffer(size_t size) { | |
288 if (last_state_.error == gpu::error::kNoError) { | |
289 int32 id; | |
290 if (Send(new PpapiHostMsg_PPBContext3D_CreateTransferBuffer( | |
291 INTERFACE_ID_PPB_CONTEXT_3D, resource_, size, &id))) { | |
292 return id; | |
293 } | |
294 } | |
295 | |
296 return -1; | |
297 } | |
298 | |
299 void PepperCommandBuffer::DestroyTransferBuffer(int32 id) { | |
300 if (last_state_.error != gpu::error::kNoError) | |
301 return; | |
302 | |
303 // Remove the transfer buffer from the client side4 cache. | |
304 TransferBufferMap::iterator it = transfer_buffers_.find(id); | |
305 DCHECK(it != transfer_buffers_.end()); | |
306 | |
307 // Delete the shared memory object, closing the handle in this process. | |
308 delete it->second.shared_memory; | |
309 | |
310 transfer_buffers_.erase(it); | |
311 | |
312 Send(new PpapiHostMsg_PPBContext3D_DestroyTransferBuffer( | |
313 INTERFACE_ID_PPB_CONTEXT_3D, resource_, id)); | |
314 } | |
315 | |
316 gpu::Buffer PepperCommandBuffer::GetTransferBuffer(int32 id) { | |
317 if (last_state_.error != gpu::error::kNoError) | |
318 return gpu::Buffer(); | |
319 | |
320 // Check local cache to see if there is already a client side shared memory | |
321 // object for this id. | |
322 TransferBufferMap::iterator it = transfer_buffers_.find(id); | |
323 if (it != transfer_buffers_.end()) { | |
324 return it->second; | |
325 } | |
326 | |
327 // Assuming we are in the renderer process, the service is responsible for | |
328 // duplicating the handle. This might not be true for NaCl. | |
329 base::SharedMemoryHandle handle; | |
330 uint32 size; | |
331 if (!Send(new PpapiHostMsg_PPBContext3D_GetTransferBuffer( | |
332 INTERFACE_ID_PPB_CONTEXT_3D, resource_, id, &handle, &size))) { | |
333 return gpu::Buffer(); | |
334 } | |
335 | |
336 // Cache the transfer buffer shared memory object client side. | |
337 base::SharedMemory* shared_memory = new base::SharedMemory(handle, false); | |
brettw
2011/01/31 18:51:29
Maybe use a scoped_ptr and .release() it when you
piman
2011/01/31 19:34:29
Done.
| |
338 | |
339 // Map the shared memory on demand. | |
340 if (!shared_memory->memory()) { | |
341 if (!shared_memory->Map(size)) { | |
342 delete shared_memory; | |
343 return gpu::Buffer(); | |
344 } | |
345 } | |
346 | |
347 gpu::Buffer buffer; | |
348 buffer.ptr = shared_memory->memory(); | |
349 buffer.size = size; | |
350 buffer.shared_memory = shared_memory; | |
351 transfer_buffers_[id] = buffer; | |
352 | |
353 return buffer; | |
354 } | |
355 | |
356 void PepperCommandBuffer::SetToken(int32 token) { | |
357 NOTREACHED(); | |
358 } | |
359 | |
360 void PepperCommandBuffer::SetParseError(gpu::error::Error error) { | |
361 NOTREACHED(); | |
362 } | |
363 | |
364 bool PepperCommandBuffer::Send(IPC::Message* msg) { | |
365 DCHECK(last_state_.error == gpu::error::kNoError); | |
366 | |
367 if (dispatcher_->Send(msg)) { | |
368 return true; | |
369 } else { | |
brettw
2011/01/31 18:51:29
Chrome style prefers no else after return.
piman
2011/01/31 19:34:29
Done.
| |
370 last_state_.error = gpu::error::kLostContext; | |
371 return false; | |
372 } | |
373 } | |
374 | |
375 Context3D::Context3D(const HostResource& resource) | |
376 : PluginResource(resource), | |
brettw
2011/01/31 18:51:29
2 more spaces.
piman
2011/01/31 19:34:29
Done.
| |
377 draw_(NULL), | |
378 read_(NULL), | |
379 transfer_buffer_id_(NULL) { | |
380 } | |
381 | |
382 Context3D::~Context3D() { | |
383 if (draw_) | |
384 draw_->set_context(NULL); | |
385 } | |
386 | |
387 bool Context3D::CreateImplementation() { | |
388 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance()); | |
389 if (!dispatcher) | |
390 return false; | |
391 | |
392 command_buffer_.reset(new PepperCommandBuffer(host_resource(), dispatcher)); | |
393 | |
394 if (!command_buffer_->Initialize(kCommandBufferSize)) | |
395 return false; | |
396 | |
397 helper_.reset(new gpu::gles2::GLES2CmdHelper(command_buffer_.get())); | |
398 if (!helper_->Initialize(kCommandBufferSize)) | |
399 return false; | |
400 | |
401 transfer_buffer_id_ = | |
402 command_buffer_->CreateTransferBuffer(kTransferBufferSize); | |
403 if (transfer_buffer_id_ < 0) | |
404 return false; | |
405 | |
406 gpu::Buffer transfer_buffer = | |
407 command_buffer_->GetTransferBuffer(transfer_buffer_id_); | |
408 if (!transfer_buffer.ptr) | |
409 return false; | |
410 | |
411 gles2_impl_.reset(new gpu::gles2::GLES2Implementation( | |
412 helper_.get(), | |
413 transfer_buffer.size, | |
414 transfer_buffer.ptr, | |
415 transfer_buffer_id_, | |
416 false)); | |
417 | |
418 return true; | |
419 } | |
420 | |
421 void Context3D::BindSurfaces(Surface3D* draw, Surface3D* read) { | |
422 if (draw != draw_) { | |
423 if (draw_) | |
424 draw_->set_context(NULL); | |
425 if (draw) { | |
426 draw->set_context(this); | |
427 // Resize the backing texture to the size of the instance when it is | |
428 // bound. | |
429 // TODO(alokp): This should be the responsibility of plugins. | |
430 PluginDispatcher* dispatcher = | |
431 PluginDispatcher::GetForInstance(instance()); | |
432 DCHECK(dispatcher); | |
433 InstanceData* data = dispatcher->GetInstanceData(instance()); | |
434 DCHECK(data); | |
435 gles2_impl()->ResizeCHROMIUM(data->position.size.width, | |
436 data->position.size.height); | |
437 } | |
438 draw_ = draw; | |
439 } | |
440 read_ = read; | |
441 } | |
442 | |
443 PPB_Context3D_Proxy::PPB_Context3D_Proxy(Dispatcher* dispatcher, | |
444 const void* target_interface) | |
445 : InterfaceProxy(dispatcher, target_interface) { | |
446 } | |
447 | |
448 PPB_Context3D_Proxy::~PPB_Context3D_Proxy() { | |
449 } | |
450 | |
451 const PPB_Context3DTrusted_Dev* | |
452 PPB_Context3D_Proxy::ppb_context_3d_trusted() const { | |
453 return static_cast<const PPB_Context3DTrusted_Dev*>( | |
454 dispatcher()->GetLocalInterface( | |
455 PPB_CONTEXT_3D_TRUSTED_DEV_INTERFACE)); | |
456 } | |
457 | |
458 const void* PPB_Context3D_Proxy::GetSourceInterface() const { | |
459 return &ppb_context_3d; | |
460 } | |
461 | |
462 InterfaceID PPB_Context3D_Proxy::GetInterfaceId() const { | |
463 return INTERFACE_ID_PPB_CONTEXT_3D; | |
464 } | |
465 | |
466 bool PPB_Context3D_Proxy::OnMessageReceived(const IPC::Message& msg) { | |
467 bool handled = true; | |
468 IPC_BEGIN_MESSAGE_MAP(PPB_Context3D_Proxy, msg) | |
469 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_Create, | |
470 OnMsgCreate) | |
471 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_BindSurfaces, | |
472 OnMsgBindSurfaces) | |
473 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_Initialize, | |
474 OnMsgInitialize) | |
475 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_GetState, | |
476 OnMsgGetState) | |
477 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_Flush, | |
478 OnMsgFlush) | |
479 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_AsyncFlush, | |
480 OnMsgAsyncFlush) | |
481 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_CreateTransferBuffer, | |
482 OnMsgCreateTransferBuffer) | |
483 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_DestroyTransferBuffer, | |
484 OnMsgDestroyTransferBuffer) | |
485 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBContext3D_GetTransferBuffer, | |
486 OnMsgGetTransferBuffer) | |
487 IPC_MESSAGE_UNHANDLED(handled = false) | |
488 | |
489 IPC_END_MESSAGE_MAP() | |
490 // FIXME(brettw) handle bad messages! | |
491 return handled; | |
492 } | |
493 | |
494 void PPB_Context3D_Proxy::OnMsgCreate(PP_Instance instance, | |
495 PP_Config3D_Dev config, | |
496 std::vector<int32_t> attribs, | |
497 HostResource* result) { | |
498 DCHECK(attribs.back() == 0); | |
499 PP_Resource resource = ppb_context_3d_trusted()->CreateRaw( | |
500 instance, config, 0, &attribs.front()); | |
501 result->SetHostResource(instance, resource); | |
502 } | |
503 | |
504 void PPB_Context3D_Proxy::OnMsgBindSurfaces(const HostResource& context, | |
505 const HostResource& draw, | |
506 const HostResource& read, | |
507 int32_t* result) { | |
508 *result = ppb_context_3d_target()->BindSurfaces(context.host_resource(), | |
509 draw.host_resource(), | |
510 read.host_resource()); | |
511 } | |
512 | |
513 void PPB_Context3D_Proxy::OnMsgInitialize( | |
514 const HostResource& context, | |
515 int32 size, | |
516 base::SharedMemoryHandle* ring_buffer) { | |
517 const PPB_Context3DTrusted_Dev* context_3d_trusted = ppb_context_3d_trusted(); | |
518 *ring_buffer = base::SharedMemory::NULLHandle(); | |
519 if (!context_3d_trusted->Initialize(context.host_resource(), size)) | |
520 return; | |
521 | |
522 int shm_handle; | |
523 uint32_t shm_size; | |
524 if (!context_3d_trusted->GetRingBuffer(context.host_resource(), | |
525 &shm_handle, | |
526 &shm_size)) { | |
527 return; | |
528 } | |
529 | |
530 *ring_buffer = SHMHandleFromInt(shm_handle); | |
531 } | |
532 | |
533 void PPB_Context3D_Proxy::OnMsgGetState(const HostResource& context, | |
534 gpu::CommandBuffer::State* state) { | |
535 PP_Context3DTrustedState pp_state = | |
536 ppb_context_3d_trusted()->GetState(context.host_resource()); | |
537 *state = GPUStateFromPPState(pp_state); | |
538 } | |
539 | |
540 void PPB_Context3D_Proxy::OnMsgFlush(const HostResource& context, | |
541 int32 put_offset, | |
542 gpu::CommandBuffer::State* state) { | |
543 PP_Context3DTrustedState pp_state = | |
544 ppb_context_3d_trusted()->FlushSync(context.host_resource(), put_offset); | |
545 *state = GPUStateFromPPState(pp_state); | |
546 } | |
547 | |
548 void PPB_Context3D_Proxy::OnMsgAsyncFlush(const HostResource& context, | |
549 int32 put_offset) { | |
550 ppb_context_3d_trusted()->Flush(context.host_resource(), put_offset); | |
551 } | |
552 | |
553 void PPB_Context3D_Proxy::OnMsgCreateTransferBuffer( | |
554 const HostResource& context, | |
555 int32 size, | |
556 int32* id) { | |
557 *id = ppb_context_3d_trusted()->CreateTransferBuffer( | |
558 context.host_resource(), size); | |
559 } | |
560 | |
561 void PPB_Context3D_Proxy::OnMsgDestroyTransferBuffer( | |
562 const HostResource& context, | |
563 int32 id) { | |
564 ppb_context_3d_trusted()->DestroyTransferBuffer(context.host_resource(), id); | |
565 } | |
566 | |
567 void PPB_Context3D_Proxy::OnMsgGetTransferBuffer( | |
568 const HostResource& context, | |
569 int32 id, | |
570 base::SharedMemoryHandle* transfer_buffer, | |
571 uint32* size) { | |
572 *transfer_buffer = base::SharedMemory::NULLHandle(); | |
573 int shm_handle; | |
574 uint32_t shm_size; | |
575 if (!ppb_context_3d_trusted()->GetTransferBuffer(context.host_resource(), | |
576 id, | |
577 &shm_handle, | |
578 &shm_size)) { | |
brettw
2011/01/31 18:51:29
Indenting.
piman
2011/01/31 19:34:29
Done.
| |
579 return; | |
580 } | |
581 *transfer_buffer = SHMHandleFromInt(shm_handle); | |
582 *size = shm_size; | |
583 } | |
584 | |
585 } // namespace proxy | |
586 } // namespace pp | |
OLD | NEW |