blob: 4e6398d1e800ebd92fe9a0efde427e797d46ed3c [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
penghuanga206fb492014-09-09 21:27:3231base::SharedMemoryHandle TransportSHMHandle(
32 Dispatcher* dispatcher,
33 const base::SharedMemoryHandle& handle) {
34 base::PlatformFile source = IPC::PlatformFileForTransitToPlatformFile(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
47Graphics3D::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
penghuanga206fb492014-09-09 21:27:3255bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2,
56 const SerializedHandle& shared_state) {
[email protected]7f8b26b2011-08-18 15:41:0157 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:0658 if (!dispatcher)
59 return false;
60
[email protected]aaa11b32012-03-08 12:30:1361 command_buffer_.reset(
penghuanga206fb492014-09-09 21:27:3262 new PpapiCommandBufferProxy(host_resource(), dispatcher, shared_state));
[email protected]84b44c552012-10-15 20:58:1763
[email protected]9ed07f82012-05-29 21:54:5564 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
65 share_gles2);
[email protected]eeb4e4a2011-07-19 16:22:0666}
67
[email protected]503b3a22011-12-12 23:29:4068PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:0669 return PP_FALSE;
70}
71
[email protected]eeb4e4a2011-07-19 16:22:0672PP_Bool Graphics3D::Flush(int32_t put_offset) {
73 return PP_FALSE;
74}
75
[email protected]046fa1ac2014-04-01 09:06:4376scoped_refptr<gpu::Buffer> Graphics3D::CreateTransferBuffer(
77 uint32_t size,
78 int32_t* id) {
79 *id = -1;
80 return NULL;
[email protected]eeb4e4a2011-07-19 16:22:0681}
82
83PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
84 return PP_FALSE;
85}
86
[email protected]7fe4198b2014-03-18 21:52:3687gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
88 int32_t end) {
89 return GetErrorState();
90}
91
92gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
93 int32_t end) {
[email protected]eeb4e4a2011-07-19 16:22:0694 return GetErrorState();
95}
96
[email protected]b096d032013-03-08 03:08:0197uint32_t Graphics3D::InsertSyncPoint() {
98 NOTREACHED();
99 return 0;
100}
101
[email protected]7035bc92014-07-01 00:27:22102uint32_t Graphics3D::InsertFutureSyncPoint() {
103 NOTREACHED();
104 return 0;
105}
106
107void Graphics3D::RetireSyncPoint(uint32_t sync_point) {
108 NOTREACHED();
109}
110
[email protected]eeb4e4a2011-07-19 16:22:06111gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
[email protected]4e46a732013-09-30 18:35:59112 return command_buffer_.get();
[email protected]eeb4e4a2011-07-19 16:22:06113}
114
[email protected]744e0792013-09-27 01:18:35115gpu::GpuControl* Graphics3D::GetGpuControl() {
116 return command_buffer_.get();
117}
118
[email protected]eeb4e4a2011-07-19 16:22:06119int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23120 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06121 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28122 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06123 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01124 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06125
[email protected]eeb4e4a2011-07-19 16:22:06126 return PP_OK_COMPLETIONPENDING;
127}
128
[email protected]5c966022011-09-13 18:09:37129PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
130 : InterfaceProxy(dispatcher),
[email protected]a2f53dc2013-04-30 01:06:35131 callback_factory_(this) {
[email protected]eeb4e4a2011-07-19 16:22:06132}
133
134PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
135}
136
137// static
[email protected]eeb4e4a2011-07-19 16:22:06138PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
139 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06140 PP_Resource share_context,
141 const int32_t* attrib_list) {
142 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
143 if (!dispatcher)
144 return PP_ERROR_BADARGUMENT;
145
[email protected]9ed07f82012-05-29 21:54:55146 HostResource share_host;
147 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
148 if (share_context != 0) {
149 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
150 if (enter.failed())
151 return PP_ERROR_BADARGUMENT;
152
153 PPB_Graphics3D_Shared* share_graphics =
154 static_cast<PPB_Graphics3D_Shared*>(enter.object());
155 share_host = share_graphics->host_resource();
156 share_gles2 = share_graphics->gles2_impl();
157 }
[email protected]eeb4e4a2011-07-19 16:22:06158
159 std::vector<int32_t> attribs;
160 if (attrib_list) {
161 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51162 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
163 attr += 2) {
164 attribs.push_back(attr[0]);
165 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06166 }
[email protected]eeb4e4a2011-07-19 16:22:06167 }
[email protected]0e50fc4d2011-08-01 15:33:51168 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06169
170 HostResource result;
penghuanga206fb492014-09-09 21:27:32171 ppapi::proxy::SerializedHandle shared_state;
172 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(API_ID_PPB_GRAPHICS_3D,
173 instance, share_host, attribs, &result, &shared_state));
174
[email protected]eeb4e4a2011-07-19 16:22:06175 if (result.is_null())
176 return 0;
177
[email protected]51e1aec2011-08-11 04:48:30178 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
penghuanga206fb492014-09-09 21:27:32179 if (!graphics_3d->Init(share_gles2, shared_state))
[email protected]eeb4e4a2011-07-19 16:22:06180 return 0;
[email protected]7f8b26b2011-08-18 15:41:01181 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06182}
183
184bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
185 bool handled = true;
186 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
[email protected]11494c5c2012-11-13 02:50:57187#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06188 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
189 OnMsgCreate)
[email protected]503b3a22011-12-12 23:29:40190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
191 OnMsgSetGetBuffer)
[email protected]7fe4198b2014-03-18 21:52:36192 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
193 OnMsgWaitForTokenInRange)
194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
195 OnMsgWaitForGetOffsetInRange)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
[email protected]eeb4e4a2011-07-19 16:22:06197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
198 OnMsgCreateTransferBuffer)
199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
200 OnMsgDestroyTransferBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
202 OnMsgSwapBuffers)
[email protected]b096d032013-03-08 03:08:01203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
204 OnMsgInsertSyncPoint)
[email protected]7035bc92014-07-01 00:27:22205 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint,
206 OnMsgInsertFutureSyncPoint)
207 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_RetireSyncPoint,
208 OnMsgRetireSyncPoint)
[email protected]11494c5c2012-11-13 02:50:57209#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06210
211 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
212 OnMsgSwapBuffersACK)
213 IPC_MESSAGE_UNHANDLED(handled = false)
214
215 IPC_END_MESSAGE_MAP()
216 // FIXME(brettw) handle bad messages!
217 return handled;
218}
219
[email protected]11494c5c2012-11-13 02:50:57220#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06221void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]9ed07f82012-05-29 21:54:55222 HostResource share_context,
[email protected]eeb4e4a2011-07-19 16:22:06223 const std::vector<int32_t>& attribs,
penghuanga206fb492014-09-09 21:27:32224 HostResource* result,
225 SerializedHandle* shared_state) {
226 shared_state->set_null_shmem();
[email protected]48c1db72012-12-17 20:56:11227 if (attribs.empty() ||
228 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
229 !(attribs.size() & 1))
[email protected]eeb4e4a2011-07-19 16:22:06230 return; // Bad message.
231
[email protected]5c966022011-09-13 18:09:37232 thunk::EnterResourceCreation enter(instance);
[email protected]9ed07f82012-05-29 21:54:55233
penghuanga206fb492014-09-09 21:27:32234 if (!enter.succeeded())
235 return;
236
237 base::SharedMemoryHandle handle = IPC::InvalidPlatformFileForTransit();
238 result->SetHostResource(
[email protected]9ed07f82012-05-29 21:54:55239 instance,
240 enter.functions()->CreateGraphics3DRaw(instance,
241 share_context.host_resource(),
penghuanga206fb492014-09-09 21:27:32242 &attribs.front(),
243 &handle));
244 if (!result->is_null()) {
245 shared_state->set_shmem(TransportSHMHandle(dispatcher(), handle),
246 sizeof(gpu::CommandBuffer::State));
[email protected]eeb4e4a2011-07-19 16:22:06247 }
248}
249
[email protected]503b3a22011-12-12 23:29:40250void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
251 const HostResource& context,
252 int32 transfer_buffer_id) {
253 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
254 if (enter.succeeded())
255 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06256}
257
[email protected]7fe4198b2014-03-18 21:52:36258void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
259 const HostResource& context,
260 int32 start,
261 int32 end,
262 gpu::CommandBuffer::State* state,
263 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06264 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35265 if (enter.failed()) {
266 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06267 return;
[email protected]571b35e82012-05-19 00:04:35268 }
[email protected]7fe4198b2014-03-18 21:52:36269 *state = enter.object()->WaitForTokenInRange(start, end);
270 *success = true;
271}
272
273void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
274 const HostResource& context,
275 int32 start,
276 int32 end,
277 gpu::CommandBuffer::State* state,
278 bool* success) {
279 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
280 if (enter.failed()) {
281 *success = false;
282 return;
283 }
284 *state = enter.object()->WaitForGetOffsetInRange(start, end);
[email protected]571b35e82012-05-19 00:04:35285 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06286}
287
288void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
289 int32 put_offset) {
290 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
291 if (enter.succeeded())
292 enter.object()->Flush(put_offset);
293}
294
295void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
296 const HostResource& context,
[email protected]b31199e2012-12-12 00:48:29297 uint32 size,
[email protected]046fa1ac2014-04-01 09:06:43298 int32* id,
penghuanga206fb492014-09-09 21:27:32299 SerializedHandle* transfer_buffer) {
[email protected]046fa1ac2014-04-01 09:06:43300 transfer_buffer->set_null_shmem();
[email protected]eeb4e4a2011-07-19 16:22:06301 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]046fa1ac2014-04-01 09:06:43302 if (enter.succeeded()) {
303 scoped_refptr<gpu::Buffer> buffer =
304 enter.object()->CreateTransferBuffer(size, id);
Daniel Cheng6d3ae972014-08-26 00:27:38305 if (!buffer.get())
[email protected]046fa1ac2014-04-01 09:06:43306 return;
[email protected]8a978df2014-04-02 23:54:09307 gpu::SharedMemoryBufferBacking* backing =
308 static_cast<gpu::SharedMemoryBufferBacking*>(buffer->backing());
309 DCHECK(backing && backing->shared_memory());
[email protected]046fa1ac2014-04-01 09:06:43310 transfer_buffer->set_shmem(
penghuanga206fb492014-09-09 21:27:32311 TransportSHMHandle(dispatcher(), backing->shared_memory()->handle()),
[email protected]046fa1ac2014-04-01 09:06:43312 buffer->size());
313 } else {
[email protected]67c80782012-12-21 01:16:52314 *id = -1;
[email protected]046fa1ac2014-04-01 09:06:43315 }
[email protected]eeb4e4a2011-07-19 16:22:06316}
317
318void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
319 const HostResource& context,
320 int32 id) {
321 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
322 if (enter.succeeded())
323 enter.object()->DestroyTransferBuffer(id);
324}
325
[email protected]eeb4e4a2011-07-19 16:22:06326void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40327 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
328 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06329 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06330 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40331 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06332}
[email protected]b096d032013-03-08 03:08:01333
334void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
335 uint32* sync_point) {
336 *sync_point = 0;
337 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
338 if (enter.succeeded())
339 *sync_point = enter.object()->InsertSyncPoint();
340}
[email protected]7035bc92014-07-01 00:27:22341
342void PPB_Graphics3D_Proxy::OnMsgInsertFutureSyncPoint(
343 const HostResource& context,
344 uint32* sync_point) {
345 *sync_point = 0;
346 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
347 if (enter.succeeded())
348 *sync_point = enter.object()->InsertFutureSyncPoint();
349}
350
351void PPB_Graphics3D_Proxy::OnMsgRetireSyncPoint(const HostResource& context,
352 uint32 sync_point) {
353 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
354 if (enter.succeeded())
355 enter.object()->RetireSyncPoint(sync_point);
356}
[email protected]11494c5c2012-11-13 02:50:57357#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06358
359void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
360 int32_t pp_error) {
361 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
362 if (enter.succeeded())
363 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
364}
365
[email protected]11494c5c2012-11-13 02:50:57366#if !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06367void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
368 int32_t result,
369 const HostResource& context) {
370 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28371 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06372}
[email protected]11494c5c2012-11-13 02:50:57373#endif // !defined(OS_NACL)
[email protected]eeb4e4a2011-07-19 16:22:06374
375} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02376} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06377