Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ppapi / proxy / ppb_graphics_3d_proxy.cc
blob4bb7b8dc4a21c53c9297e667e76807186e8546d8
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/ppb_graphics_3d_proxy.h"
7 #include "gpu/command_buffer/client/gles2_implementation.h"
8 #include "gpu/command_buffer/common/command_buffer.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/proxy/enter_proxy.h"
11 #include "ppapi/proxy/plugin_dispatcher.h"
12 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/ppapi_globals.h"
15 #include "ppapi/thunk/enter.h"
16 #include "ppapi/thunk/resource_creation_api.h"
17 #include "ppapi/thunk/thunk.h"
19 using ppapi::thunk::EnterResourceNoLock;
20 using ppapi::thunk::PPB_Graphics3D_API;
21 using ppapi::thunk::ResourceCreationAPI;
23 namespace ppapi {
24 namespace proxy {
26 namespace {
28 const int32 kCommandBufferSize = 1024 * 1024;
29 const int32 kTransferBufferSize = 1024 * 1024;
31 base::SharedMemoryHandle TransportSHMHandle(Dispatcher* dispatcher,
32 base::SharedMemory* shm) {
33 base::PlatformFile source =
34 IPC::PlatformFileForTransitToPlatformFile(shm->handle());
35 // Don't close the handle, it doesn't belong to us.
36 return dispatcher->ShareHandleWithRemote(source, false);
39 gpu::CommandBuffer::State GetErrorState() {
40 gpu::CommandBuffer::State error_state;
41 error_state.error = gpu::error::kGenericError;
42 return error_state;
45 } // namespace
47 Graphics3D::Graphics3D(const HostResource& resource)
48 : PPB_Graphics3D_Shared(resource) {
51 Graphics3D::~Graphics3D() {
52 DestroyGLES2Impl();
55 bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
56 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
57 if (!dispatcher)
58 return false;
60 command_buffer_.reset(
61 new PpapiCommandBufferProxy(host_resource(), dispatcher));
63 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
64 share_gles2);
67 PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
68 return PP_FALSE;
71 PP_Bool Graphics3D::Flush(int32_t put_offset) {
72 return PP_FALSE;
75 scoped_refptr<gpu::Buffer> Graphics3D::CreateTransferBuffer(
76 uint32_t size,
77 int32_t* id) {
78 *id = -1;
79 return NULL;
82 PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
83 return PP_FALSE;
86 gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
87 int32_t end) {
88 return GetErrorState();
91 gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
92 int32_t end) {
93 return GetErrorState();
96 uint32_t Graphics3D::InsertSyncPoint() {
97 NOTREACHED();
98 return 0;
101 uint32_t Graphics3D::InsertFutureSyncPoint() {
102 NOTREACHED();
103 return 0;
106 void Graphics3D::RetireSyncPoint(uint32_t sync_point) {
107 NOTREACHED();
110 gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
111 return command_buffer_.get();
114 gpu::GpuControl* Graphics3D::GetGpuControl() {
115 return command_buffer_.get();
118 int32 Graphics3D::DoSwapBuffers() {
119 gles2_impl()->SwapBuffers();
120 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
121 API_ID_PPB_GRAPHICS_3D, host_resource());
122 msg->set_unblock(true);
123 PluginDispatcher::GetForResource(this)->Send(msg);
125 return PP_OK_COMPLETIONPENDING;
128 PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
129 : InterfaceProxy(dispatcher),
130 callback_factory_(this) {
133 PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
136 // static
137 PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
138 PP_Instance instance,
139 PP_Resource share_context,
140 const int32_t* attrib_list) {
141 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
142 if (!dispatcher)
143 return PP_ERROR_BADARGUMENT;
145 HostResource share_host;
146 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
147 if (share_context != 0) {
148 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
149 if (enter.failed())
150 return PP_ERROR_BADARGUMENT;
152 PPB_Graphics3D_Shared* share_graphics =
153 static_cast<PPB_Graphics3D_Shared*>(enter.object());
154 share_host = share_graphics->host_resource();
155 share_gles2 = share_graphics->gles2_impl();
158 std::vector<int32_t> attribs;
159 if (attrib_list) {
160 for (const int32_t* attr = attrib_list;
161 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
162 attr += 2) {
163 attribs.push_back(attr[0]);
164 attribs.push_back(attr[1]);
167 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
169 HostResource result;
170 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
171 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
172 if (result.is_null())
173 return 0;
175 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
176 if (!graphics_3d->Init(share_gles2))
177 return 0;
178 return graphics_3d->GetReference();
181 bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
182 bool handled = true;
183 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
184 #if !defined(OS_NACL)
185 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
186 OnMsgCreate)
187 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
188 OnMsgSetGetBuffer)
189 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
190 OnMsgWaitForTokenInRange)
191 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
192 OnMsgWaitForGetOffsetInRange)
193 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
195 OnMsgCreateTransferBuffer)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
197 OnMsgDestroyTransferBuffer)
198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
199 OnMsgSwapBuffers)
200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
201 OnMsgInsertSyncPoint)
202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint,
203 OnMsgInsertFutureSyncPoint)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_RetireSyncPoint,
205 OnMsgRetireSyncPoint)
206 #endif // !defined(OS_NACL)
208 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
209 OnMsgSwapBuffersACK)
210 IPC_MESSAGE_UNHANDLED(handled = false)
212 IPC_END_MESSAGE_MAP()
213 // FIXME(brettw) handle bad messages!
214 return handled;
217 #if !defined(OS_NACL)
218 void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
219 HostResource share_context,
220 const std::vector<int32_t>& attribs,
221 HostResource* result) {
222 if (attribs.empty() ||
223 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
224 !(attribs.size() & 1))
225 return; // Bad message.
227 thunk::EnterResourceCreation enter(instance);
229 if (enter.succeeded()) {
230 result->SetHostResource(
231 instance,
232 enter.functions()->CreateGraphics3DRaw(instance,
233 share_context.host_resource(),
234 &attribs.front()));
238 void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
239 const HostResource& context,
240 int32 transfer_buffer_id) {
241 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
242 if (enter.succeeded())
243 enter.object()->SetGetBuffer(transfer_buffer_id);
246 void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
247 const HostResource& context,
248 int32 start,
249 int32 end,
250 gpu::CommandBuffer::State* state,
251 bool* success) {
252 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
253 if (enter.failed()) {
254 *success = false;
255 return;
257 *state = enter.object()->WaitForTokenInRange(start, end);
258 *success = true;
261 void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
262 const HostResource& context,
263 int32 start,
264 int32 end,
265 gpu::CommandBuffer::State* state,
266 bool* success) {
267 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
268 if (enter.failed()) {
269 *success = false;
270 return;
272 *state = enter.object()->WaitForGetOffsetInRange(start, end);
273 *success = true;
276 void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
277 int32 put_offset) {
278 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
279 if (enter.succeeded())
280 enter.object()->Flush(put_offset);
283 void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
284 const HostResource& context,
285 uint32 size,
286 int32* id,
287 ppapi::proxy::SerializedHandle* transfer_buffer) {
288 transfer_buffer->set_null_shmem();
289 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
290 if (enter.succeeded()) {
291 scoped_refptr<gpu::Buffer> buffer =
292 enter.object()->CreateTransferBuffer(size, id);
293 if (!buffer.get())
294 return;
295 gpu::SharedMemoryBufferBacking* backing =
296 static_cast<gpu::SharedMemoryBufferBacking*>(buffer->backing());
297 DCHECK(backing && backing->shared_memory());
298 transfer_buffer->set_shmem(
299 TransportSHMHandle(dispatcher(), backing->shared_memory()),
300 buffer->size());
301 } else {
302 *id = -1;
306 void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
307 const HostResource& context,
308 int32 id) {
309 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
310 if (enter.succeeded())
311 enter.object()->DestroyTransferBuffer(id);
314 void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
315 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
316 context, callback_factory_,
317 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
318 if (enter.succeeded())
319 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
322 void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
323 uint32* sync_point) {
324 *sync_point = 0;
325 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
326 if (enter.succeeded())
327 *sync_point = enter.object()->InsertSyncPoint();
330 void PPB_Graphics3D_Proxy::OnMsgInsertFutureSyncPoint(
331 const HostResource& context,
332 uint32* sync_point) {
333 *sync_point = 0;
334 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
335 if (enter.succeeded())
336 *sync_point = enter.object()->InsertFutureSyncPoint();
339 void PPB_Graphics3D_Proxy::OnMsgRetireSyncPoint(const HostResource& context,
340 uint32 sync_point) {
341 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
342 if (enter.succeeded())
343 enter.object()->RetireSyncPoint(sync_point);
345 #endif // !defined(OS_NACL)
347 void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
348 int32_t pp_error) {
349 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
350 if (enter.succeeded())
351 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
354 #if !defined(OS_NACL)
355 void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
356 int32_t result,
357 const HostResource& context) {
358 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
359 API_ID_PPB_GRAPHICS_3D, context, result));
361 #endif // !defined(OS_NACL)
363 } // namespace proxy
364 } // namespace ppapi