blob: 85692d40569bd2273f1a140461bdf993a78bf26c [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]046fa1ac2014-04-01 09:06:4331base::SharedMemoryHandle TransportSHMHandle(Dispatcher* dispatcher,
32 base::SharedMemory* shm) {
[email protected]eeb4e4a2011-07-19 16:22:0633 base::PlatformFile source =
[email protected]046fa1ac2014-04-01 09:06:4334 IPC::PlatformFileForTransitToPlatformFile(shm->handle());
[email protected]eeb4e4a2011-07-19 16:22:0635 // Don't close the handle, it doesn't belong to us.
36 return dispatcher->ShareHandleWithRemote(source, false);
37}
38
[email protected]914f5262013-06-01 00:17:2239gpu::CommandBuffer::State GetErrorState() {
40 gpu::CommandBuffer::State error_state;
41 error_state.error = gpu::error::kGenericError;
[email protected]eeb4e4a2011-07-19 16:22:0642 return error_state;
43}
44
[email protected]eeb4e4a2011-07-19 16:22:0645} // namespace
46
[email protected]eeb4e4a2011-07-19 16:22:0647Graphics3D::Graphics3D(const HostResource& resource)
[email protected]4e46a732013-09-30 18:35:5948 : PPB_Graphics3D_Shared(resource) {
[email protected]eeb4e4a2011-07-19 16:22:0649}
50
51Graphics3D::~Graphics3D() {
[email protected]edccb562013-10-02 00:01:2052 DestroyGLES2Impl();
[email protected]eeb4e4a2011-07-19 16:22:0653}
54
[email protected]9ed07f82012-05-29 21:54:5555bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
[email protected]7f8b26b2011-08-18 15:41:0156 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:0657 if (!dispatcher)
58 return false;
59
[email protected]aaa11b32012-03-08 12:30:1360 command_buffer_.reset(
61 new PpapiCommandBufferProxy(host_resource(), dispatcher));
[email protected]84b44c552012-10-15 20:58:1762
[email protected]9ed07f82012-05-29 21:54:5563 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
64 share_gles2);
[email protected]eeb4e4a2011-07-19 16:22:0665}
66
[email protected]503b3a22011-12-12 23:29:4067PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:0668 return PP_FALSE;
69}
70
[email protected]914f5262013-06-01 00:17:2271gpu::CommandBuffer::State Graphics3D::GetState() {
[email protected]eeb4e4a2011-07-19 16:22:0672 return GetErrorState();
73}
74
75PP_Bool Graphics3D::Flush(int32_t put_offset) {
76 return PP_FALSE;
77}
78
[email protected]046fa1ac2014-04-01 09:06:4379scoped_refptr<gpu::Buffer> Graphics3D::CreateTransferBuffer(
80 uint32_t size,
81 int32_t* id) {
82 *id = -1;
83 return NULL;
[email protected]eeb4e4a2011-07-19 16:22:0684}
85
86PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
87 return PP_FALSE;
88}
89
[email protected]7fe4198b2014-03-18 21:52:3690gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
91 int32_t end) {
92 return GetErrorState();
93}
94
95gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
96 int32_t end) {
[email protected]eeb4e4a2011-07-19 16:22:0697 return GetErrorState();
98}
99
[email protected]b096d032013-03-08 03:08:01100uint32_t Graphics3D::InsertSyncPoint() {
101 NOTREACHED();
102 return 0;
103}
104
[email protected]eeb4e4a2011-07-19 16:22:06105gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
[email protected]4e46a732013-09-30 18:35:59106 return command_buffer_.get();
[email protected]eeb4e4a2011-07-19 16:22:06107}
108
[email protected]744e0792013-09-27 01:18:35109gpu::GpuControl* Graphics3D::GetGpuControl() {
110 return command_buffer_.get();
111}
112
[email protected]eeb4e4a2011-07-19 16:22:06113int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23114 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06115 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28116 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06117 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01118 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06119
[email protected]eeb4e4a2011-07-19 16:22:06120 return PP_OK_COMPLETIONPENDING;
121}
122
[email protected]5c966022011-09-13 18:09:37123PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
124 : InterfaceProxy(dispatcher),
[email protected]a2f53dc2013-04-30 01:06:35125 callback_factory_(this) {
[email protected]eeb4e4a2011-07-19 16:22:06126}
127
128PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
129}
130
131// static
[email protected]eeb4e4a2011-07-19 16:22:06132PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
133 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06134 PP_Resource share_context,
135 const int32_t* attrib_list) {
136 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
137 if (!dispatcher)
138 return PP_ERROR_BADARGUMENT;
139
[email protected]9ed07f82012-05-29 21:54:55140 HostResource share_host;
141 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
142 if (share_context != 0) {
143 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
144 if (enter.failed())
145 return PP_ERROR_BADARGUMENT;
146
147 PPB_Graphics3D_Shared* share_graphics =
148 static_cast<PPB_Graphics3D_Shared*>(enter.object());
149 share_host = share_graphics->host_resource();
150 share_gles2 = share_graphics->gles2_impl();
151 }
[email protected]eeb4e4a2011-07-19 16:22:06152
153 std::vector<int32_t> attribs;
154 if (attrib_list) {
155 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51156 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
157 attr += 2) {
158 attribs.push_back(attr[0]);
159 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06160 }
[email protected]eeb4e4a2011-07-19 16:22:06161 }
[email protected]0e50fc4d2011-08-01 15:33:51162 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06163
164 HostResource result;
165 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]9ed07f82012-05-29 21:54:55166 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06167 if (result.is_null())
168 return 0;
169
[email protected]51e1aec2011-08-11 04:48:30170 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]9ed07f82012-05-29 21:54:55171 if (!graphics_3d->Init(share_gles2))
[email protected]eeb4e4a2011-07-19 16:22:06172 return 0;
[email protected]7f8b26b2011-08-18 15:41:01173 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06174}
175
176bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
177 bool handled = true;
178 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
[email protected]11494c5c2012-11-13 02:50:57179#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06180 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
181 OnMsgCreate)
[email protected]503b3a22011-12-12 23:29:40182 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
183 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06184 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
185 OnMsgGetState)
[email protected]7fe4198b2014-03-18 21:52:36186 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
187 OnMsgWaitForTokenInRange)
188 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
189 OnMsgWaitForGetOffsetInRange)
190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
[email protected]eeb4e4a2011-07-19 16:22:06191 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
192 OnMsgCreateTransferBuffer)
193 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
194 OnMsgDestroyTransferBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
196 OnMsgSwapBuffers)
[email protected]b096d032013-03-08 03:08:01197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
198 OnMsgInsertSyncPoint)
[email protected]11494c5c2012-11-13 02:50:57199#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06200
201 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
202 OnMsgSwapBuffersACK)
203 IPC_MESSAGE_UNHANDLED(handled = false)
204
205 IPC_END_MESSAGE_MAP()
206 // FIXME(brettw) handle bad messages!
207 return handled;
208}
209
[email protected]11494c5c2012-11-13 02:50:57210#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06211void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]9ed07f82012-05-29 21:54:55212 HostResource share_context,
[email protected]eeb4e4a2011-07-19 16:22:06213 const std::vector<int32_t>& attribs,
214 HostResource* result) {
[email protected]48c1db72012-12-17 20:56:11215 if (attribs.empty() ||
216 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
217 !(attribs.size() & 1))
[email protected]eeb4e4a2011-07-19 16:22:06218 return; // Bad message.
219
[email protected]5c966022011-09-13 18:09:37220 thunk::EnterResourceCreation enter(instance);
[email protected]9ed07f82012-05-29 21:54:55221
[email protected]eeb4e4a2011-07-19 16:22:06222 if (enter.succeeded()) {
223 result->SetHostResource(
[email protected]9ed07f82012-05-29 21:54:55224 instance,
225 enter.functions()->CreateGraphics3DRaw(instance,
226 share_context.host_resource(),
227 &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06228 }
229}
230
[email protected]503b3a22011-12-12 23:29:40231void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
232 const HostResource& context,
233 int32 transfer_buffer_id) {
234 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
235 if (enter.succeeded())
236 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06237}
238
239void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
[email protected]571b35e82012-05-19 00:04:35240 gpu::CommandBuffer::State* state,
241 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06242 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35243 if (enter.failed()) {
244 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06245 return;
[email protected]571b35e82012-05-19 00:04:35246 }
[email protected]914f5262013-06-01 00:17:22247 *state = enter.object()->GetState();
[email protected]571b35e82012-05-19 00:04:35248 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06249}
250
[email protected]7fe4198b2014-03-18 21:52:36251void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
252 const HostResource& context,
253 int32 start,
254 int32 end,
255 gpu::CommandBuffer::State* state,
256 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06257 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35258 if (enter.failed()) {
259 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06260 return;
[email protected]571b35e82012-05-19 00:04:35261 }
[email protected]7fe4198b2014-03-18 21:52:36262 *state = enter.object()->WaitForTokenInRange(start, end);
263 *success = true;
264}
265
266void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
267 const HostResource& context,
268 int32 start,
269 int32 end,
270 gpu::CommandBuffer::State* state,
271 bool* success) {
272 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
273 if (enter.failed()) {
274 *success = false;
275 return;
276 }
277 *state = enter.object()->WaitForGetOffsetInRange(start, end);
[email protected]571b35e82012-05-19 00:04:35278 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06279}
280
281void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
282 int32 put_offset) {
283 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
284 if (enter.succeeded())
285 enter.object()->Flush(put_offset);
286}
287
288void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
289 const HostResource& context,
[email protected]b31199e2012-12-12 00:48:29290 uint32 size,
[email protected]046fa1ac2014-04-01 09:06:43291 int32* id,
292 ppapi::proxy::SerializedHandle* transfer_buffer) {
293 transfer_buffer->set_null_shmem();
[email protected]eeb4e4a2011-07-19 16:22:06294 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]046fa1ac2014-04-01 09:06:43295 if (enter.succeeded()) {
296 scoped_refptr<gpu::Buffer> buffer =
297 enter.object()->CreateTransferBuffer(size, id);
298 if (!buffer)
299 return;
[email protected]8a978df2014-04-02 23:54:09300 gpu::SharedMemoryBufferBacking* backing =
301 static_cast<gpu::SharedMemoryBufferBacking*>(buffer->backing());
302 DCHECK(backing && backing->shared_memory());
[email protected]046fa1ac2014-04-01 09:06:43303 transfer_buffer->set_shmem(
[email protected]8a978df2014-04-02 23:54:09304 TransportSHMHandle(dispatcher(), backing->shared_memory()),
[email protected]046fa1ac2014-04-01 09:06:43305 buffer->size());
306 } else {
[email protected]67c80782012-12-21 01:16:52307 *id = -1;
[email protected]046fa1ac2014-04-01 09:06:43308 }
[email protected]eeb4e4a2011-07-19 16:22:06309}
310
311void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
312 const HostResource& context,
313 int32 id) {
314 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
315 if (enter.succeeded())
316 enter.object()->DestroyTransferBuffer(id);
317}
318
[email protected]eeb4e4a2011-07-19 16:22:06319void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40320 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
321 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06322 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06323 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40324 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06325}
[email protected]b096d032013-03-08 03:08:01326
327void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
328 uint32* sync_point) {
329 *sync_point = 0;
330 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
331 if (enter.succeeded())
332 *sync_point = enter.object()->InsertSyncPoint();
333}
[email protected]11494c5c2012-11-13 02:50:57334#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06335
336void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
337 int32_t pp_error) {
338 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
339 if (enter.succeeded())
340 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
341}
342
[email protected]11494c5c2012-11-13 02:50:57343#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06344void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
345 int32_t result,
346 const HostResource& context) {
347 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28348 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06349}
[email protected]11494c5c2012-11-13 02:50:57350#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06351
352} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02353} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06354