blob: 847e294680d2acaa5b4a5d07f0c53f0fc4ed7215 [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"
[email protected]eeb4e4a2011-07-19 16:22:0615#include "ppapi/thunk/enter.h"
16#include "ppapi/thunk/resource_creation_api.h"
17#include "ppapi/thunk/thunk.h"
18
[email protected]eeb4e4a2011-07-19 16:22:0619using ppapi::thunk::EnterResourceNoLock;
20using ppapi::thunk::PPB_Graphics3D_API;
21using ppapi::thunk::ResourceCreationAPI;
22
[email protected]4d2efd22011-08-18 21:58:0223namespace ppapi {
[email protected]eeb4e4a2011-07-19 16:22:0624namespace proxy {
25
26namespace {
[email protected]84b44c552012-10-15 20:58:1727
[email protected]eeb4e4a2011-07-19 16:22:0628const int32 kCommandBufferSize = 1024 * 1024;
29const int32 kTransferBufferSize = 1024 * 1024;
30
[email protected]eeb4e4a2011-07-19 16:22:0631base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
32 int shm_handle) {
33 // TODO(piman): Change trusted interface to return a PP_FileHandle, those
34 // casts are ugly.
35 base::PlatformFile source =
36#if defined(OS_WIN)
37 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shm_handle));
38#elif defined(OS_POSIX)
39 shm_handle;
40#else
41 #error Not implemented.
42#endif
43 // Don't close the handle, it doesn't belong to us.
44 return dispatcher->ShareHandleWithRemote(source, false);
45}
46
[email protected]914f5262013-06-01 00:17:2247gpu::CommandBuffer::State GetErrorState() {
48 gpu::CommandBuffer::State error_state;
49 error_state.error = gpu::error::kGenericError;
[email protected]eeb4e4a2011-07-19 16:22:0650 return error_state;
51}
52
[email protected]eeb4e4a2011-07-19 16:22:0653} // namespace
54
[email protected]eeb4e4a2011-07-19 16:22:0655Graphics3D::Graphics3D(const HostResource& resource)
[email protected]4e46a732013-09-30 18:35:5956 : PPB_Graphics3D_Shared(resource) {
[email protected]eeb4e4a2011-07-19 16:22:0657}
58
59Graphics3D::~Graphics3D() {
[email protected]edccb562013-10-02 00:01:2060 DestroyGLES2Impl();
[email protected]eeb4e4a2011-07-19 16:22:0661}
62
[email protected]9ed07f82012-05-29 21:54:5563bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
[email protected]7f8b26b2011-08-18 15:41:0164 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:0665 if (!dispatcher)
66 return false;
67
[email protected]aaa11b32012-03-08 12:30:1368 command_buffer_.reset(
69 new PpapiCommandBufferProxy(host_resource(), dispatcher));
[email protected]84b44c552012-10-15 20:58:1770
[email protected]9ed07f82012-05-29 21:54:5571 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
72 share_gles2);
[email protected]eeb4e4a2011-07-19 16:22:0673}
74
[email protected]503b3a22011-12-12 23:29:4075PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:0676 return PP_FALSE;
77}
78
[email protected]914f5262013-06-01 00:17:2279gpu::CommandBuffer::State Graphics3D::GetState() {
[email protected]eeb4e4a2011-07-19 16:22:0680 return GetErrorState();
81}
82
83PP_Bool Graphics3D::Flush(int32_t put_offset) {
84 return PP_FALSE;
85}
86
[email protected]eeb4e4a2011-07-19 16:22:0687int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
88 return PP_FALSE;
89}
90
91PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
92 return PP_FALSE;
93}
94
95PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
96 int* shm_handle,
97 uint32_t* shm_size) {
98 return PP_FALSE;
99}
100
[email protected]7fe4198b2014-03-18 21:52:36101gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
102 int32_t end) {
103 return GetErrorState();
104}
105
106gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
107 int32_t end) {
[email protected]eeb4e4a2011-07-19 16:22:06108 return GetErrorState();
109}
110
[email protected]b096d032013-03-08 03:08:01111uint32_t Graphics3D::InsertSyncPoint() {
112 NOTREACHED();
113 return 0;
114}
115
[email protected]eeb4e4a2011-07-19 16:22:06116gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
[email protected]4e46a732013-09-30 18:35:59117 return command_buffer_.get();
[email protected]eeb4e4a2011-07-19 16:22:06118}
119
[email protected]744e0792013-09-27 01:18:35120gpu::GpuControl* Graphics3D::GetGpuControl() {
121 return command_buffer_.get();
122}
123
[email protected]eeb4e4a2011-07-19 16:22:06124int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23125 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06126 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28127 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06128 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01129 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06130
[email protected]eeb4e4a2011-07-19 16:22:06131 return PP_OK_COMPLETIONPENDING;
132}
133
[email protected]5c966022011-09-13 18:09:37134PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
135 : InterfaceProxy(dispatcher),
[email protected]a2f53dc2013-04-30 01:06:35136 callback_factory_(this) {
[email protected]eeb4e4a2011-07-19 16:22:06137}
138
139PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
140}
141
142// static
[email protected]eeb4e4a2011-07-19 16:22:06143PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
144 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06145 PP_Resource share_context,
146 const int32_t* attrib_list) {
147 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
148 if (!dispatcher)
149 return PP_ERROR_BADARGUMENT;
150
[email protected]9ed07f82012-05-29 21:54:55151 HostResource share_host;
152 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
153 if (share_context != 0) {
154 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
155 if (enter.failed())
156 return PP_ERROR_BADARGUMENT;
157
158 PPB_Graphics3D_Shared* share_graphics =
159 static_cast<PPB_Graphics3D_Shared*>(enter.object());
160 share_host = share_graphics->host_resource();
161 share_gles2 = share_graphics->gles2_impl();
162 }
[email protected]eeb4e4a2011-07-19 16:22:06163
164 std::vector<int32_t> attribs;
165 if (attrib_list) {
166 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51167 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
168 attr += 2) {
169 attribs.push_back(attr[0]);
170 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06171 }
[email protected]eeb4e4a2011-07-19 16:22:06172 }
[email protected]0e50fc4d2011-08-01 15:33:51173 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06174
175 HostResource result;
176 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]9ed07f82012-05-29 21:54:55177 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06178 if (result.is_null())
179 return 0;
180
[email protected]51e1aec2011-08-11 04:48:30181 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]9ed07f82012-05-29 21:54:55182 if (!graphics_3d->Init(share_gles2))
[email protected]eeb4e4a2011-07-19 16:22:06183 return 0;
[email protected]7f8b26b2011-08-18 15:41:01184 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06185}
186
187bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
188 bool handled = true;
189 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
[email protected]11494c5c2012-11-13 02:50:57190#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06191 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
192 OnMsgCreate)
[email protected]503b3a22011-12-12 23:29:40193 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
194 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
196 OnMsgGetState)
[email protected]7fe4198b2014-03-18 21:52:36197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
198 OnMsgWaitForTokenInRange)
199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
200 OnMsgWaitForGetOffsetInRange)
201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
[email protected]eeb4e4a2011-07-19 16:22:06202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
203 OnMsgCreateTransferBuffer)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
205 OnMsgDestroyTransferBuffer)
206 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
207 OnMsgGetTransferBuffer)
208 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
209 OnMsgSwapBuffers)
[email protected]b096d032013-03-08 03:08:01210 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
211 OnMsgInsertSyncPoint)
[email protected]11494c5c2012-11-13 02:50:57212#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06213
214 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
215 OnMsgSwapBuffersACK)
216 IPC_MESSAGE_UNHANDLED(handled = false)
217
218 IPC_END_MESSAGE_MAP()
219 // FIXME(brettw) handle bad messages!
220 return handled;
221}
222
[email protected]11494c5c2012-11-13 02:50:57223#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06224void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]9ed07f82012-05-29 21:54:55225 HostResource share_context,
[email protected]eeb4e4a2011-07-19 16:22:06226 const std::vector<int32_t>& attribs,
227 HostResource* result) {
[email protected]48c1db72012-12-17 20:56:11228 if (attribs.empty() ||
229 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
230 !(attribs.size() & 1))
[email protected]eeb4e4a2011-07-19 16:22:06231 return; // Bad message.
232
[email protected]5c966022011-09-13 18:09:37233 thunk::EnterResourceCreation enter(instance);
[email protected]9ed07f82012-05-29 21:54:55234
[email protected]eeb4e4a2011-07-19 16:22:06235 if (enter.succeeded()) {
236 result->SetHostResource(
[email protected]9ed07f82012-05-29 21:54:55237 instance,
238 enter.functions()->CreateGraphics3DRaw(instance,
239 share_context.host_resource(),
240 &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06241 }
242}
243
[email protected]503b3a22011-12-12 23:29:40244void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
245 const HostResource& context,
246 int32 transfer_buffer_id) {
247 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
248 if (enter.succeeded())
249 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06250}
251
252void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
[email protected]571b35e82012-05-19 00:04:35253 gpu::CommandBuffer::State* state,
254 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06255 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35256 if (enter.failed()) {
257 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06258 return;
[email protected]571b35e82012-05-19 00:04:35259 }
[email protected]914f5262013-06-01 00:17:22260 *state = enter.object()->GetState();
[email protected]571b35e82012-05-19 00:04:35261 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06262}
263
[email protected]7fe4198b2014-03-18 21:52:36264void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
265 const HostResource& context,
266 int32 start,
267 int32 end,
268 gpu::CommandBuffer::State* state,
269 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06270 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35271 if (enter.failed()) {
272 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06273 return;
[email protected]571b35e82012-05-19 00:04:35274 }
[email protected]7fe4198b2014-03-18 21:52:36275 *state = enter.object()->WaitForTokenInRange(start, end);
276 *success = true;
277}
278
279void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
280 const HostResource& context,
281 int32 start,
282 int32 end,
283 gpu::CommandBuffer::State* state,
284 bool* success) {
285 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
286 if (enter.failed()) {
287 *success = false;
288 return;
289 }
290 *state = enter.object()->WaitForGetOffsetInRange(start, end);
[email protected]571b35e82012-05-19 00:04:35291 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06292}
293
294void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
295 int32 put_offset) {
296 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
297 if (enter.succeeded())
298 enter.object()->Flush(put_offset);
299}
300
301void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
302 const HostResource& context,
[email protected]b31199e2012-12-12 00:48:29303 uint32 size,
[email protected]eeb4e4a2011-07-19 16:22:06304 int32* id) {
305 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
306 if (enter.succeeded())
307 *id = enter.object()->CreateTransferBuffer(size);
308 else
[email protected]67c80782012-12-21 01:16:52309 *id = -1;
[email protected]eeb4e4a2011-07-19 16:22:06310}
311
312void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
313 const HostResource& context,
314 int32 id) {
315 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
316 if (enter.succeeded())
317 enter.object()->DestroyTransferBuffer(id);
318}
319
320void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
321 const HostResource& context,
322 int32 id,
[email protected]246fc492012-08-27 20:28:18323 ppapi::proxy::SerializedHandle* transfer_buffer) {
324 transfer_buffer->set_null_shmem();
[email protected]eeb4e4a2011-07-19 16:22:06325
326 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
327 int shm_handle = 0;
328 uint32_t shm_size = 0;
329 if (enter.succeeded() &&
330 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
[email protected]246fc492012-08-27 20:28:18331 transfer_buffer->set_shmem(
332 TransportSHMHandleFromInt(dispatcher(), shm_handle),
333 shm_size);
[email protected]eeb4e4a2011-07-19 16:22:06334 }
335}
336
337void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40338 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
339 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06340 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06341 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40342 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06343}
[email protected]b096d032013-03-08 03:08:01344
345void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
346 uint32* sync_point) {
347 *sync_point = 0;
348 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
349 if (enter.succeeded())
350 *sync_point = enter.object()->InsertSyncPoint();
351}
[email protected]11494c5c2012-11-13 02:50:57352#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06353
354void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
355 int32_t pp_error) {
356 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
357 if (enter.succeeded())
358 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
359}
360
[email protected]11494c5c2012-11-13 02:50:57361#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06362void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
363 int32_t result,
364 const HostResource& context) {
365 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28366 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06367}
[email protected]11494c5c2012-11-13 02:50:57368#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06369
370} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02371} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06372