blob: 25bcd44f956e5b725ab13a5f25dbf4000cd2db70 [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"
8#include "ppapi/c/pp_errors.h"
9#include "ppapi/proxy/enter_proxy.h"
10#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]aaa11b32012-03-08 12:30:1311#include "ppapi/proxy/ppapi_command_buffer_proxy.h"
[email protected]eeb4e4a2011-07-19 16:22:0612#include "ppapi/proxy/ppapi_messages.h"
13#include "ppapi/thunk/enter.h"
14#include "ppapi/thunk/resource_creation_api.h"
15#include "ppapi/thunk/thunk.h"
16
[email protected]eeb4e4a2011-07-19 16:22:0617using ppapi::thunk::EnterResourceNoLock;
18using ppapi::thunk::PPB_Graphics3D_API;
19using ppapi::thunk::ResourceCreationAPI;
20
[email protected]4d2efd22011-08-18 21:58:0221namespace ppapi {
[email protected]eeb4e4a2011-07-19 16:22:0622namespace proxy {
23
24namespace {
25const int32 kCommandBufferSize = 1024 * 1024;
26const int32 kTransferBufferSize = 1024 * 1024;
27
[email protected]eeb4e4a2011-07-19 16:22:0628base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
29 int shm_handle) {
30 // TODO(piman): Change trusted interface to return a PP_FileHandle, those
31 // casts are ugly.
32 base::PlatformFile source =
33#if defined(OS_WIN)
34 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shm_handle));
35#elif defined(OS_POSIX)
36 shm_handle;
37#else
38 #error Not implemented.
39#endif
40 // Don't close the handle, it doesn't belong to us.
41 return dispatcher->ShareHandleWithRemote(source, false);
42}
43
44PP_Graphics3DTrustedState GetErrorState() {
45 PP_Graphics3DTrustedState error_state = { 0 };
46 error_state.error = PPB_GRAPHICS3D_TRUSTED_ERROR_GENERICERROR;
47 return error_state;
48}
49
50gpu::CommandBuffer::State GPUStateFromPPState(
51 const PP_Graphics3DTrustedState& s) {
52 gpu::CommandBuffer::State state;
53 state.num_entries = s.num_entries;
54 state.get_offset = s.get_offset;
55 state.put_offset = s.put_offset;
56 state.token = s.token;
57 state.error = static_cast<gpu::error::Error>(s.error);
58 state.generation = s.generation;
59 return state;
60}
61
[email protected]eeb4e4a2011-07-19 16:22:0662} // namespace
63
64Graphics3D::Graphics3D(const HostResource& resource)
[email protected]614888b2012-01-05 06:18:1265 : PPB_Graphics3D_Shared(resource) {
[email protected]eeb4e4a2011-07-19 16:22:0666}
67
68Graphics3D::~Graphics3D() {
69 DestroyGLES2Impl();
70}
71
[email protected]9ed07f82012-05-29 21:54:5572bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
[email protected]7f8b26b2011-08-18 15:41:0173 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
[email protected]eeb4e4a2011-07-19 16:22:0674 if (!dispatcher)
75 return false;
76
[email protected]aaa11b32012-03-08 12:30:1377 command_buffer_.reset(
78 new PpapiCommandBufferProxy(host_resource(), dispatcher));
[email protected]503b3a22011-12-12 23:29:4079 if (!command_buffer_->Initialize())
[email protected]0e50fc4d2011-08-01 15:33:5180 return false;
[email protected]eeb4e4a2011-07-19 16:22:0681
[email protected]9ed07f82012-05-29 21:54:5582 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
83 share_gles2);
[email protected]eeb4e4a2011-07-19 16:22:0684}
85
[email protected]503b3a22011-12-12 23:29:4086PP_Bool Graphics3D::InitCommandBuffer() {
[email protected]eeb4e4a2011-07-19 16:22:0687 return PP_FALSE;
88}
89
[email protected]503b3a22011-12-12 23:29:4090PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:0691 return PP_FALSE;
92}
93
94PP_Graphics3DTrustedState Graphics3D::GetState() {
95 return GetErrorState();
96}
97
98PP_Bool Graphics3D::Flush(int32_t put_offset) {
99 return PP_FALSE;
100}
101
102PP_Graphics3DTrustedState Graphics3D::FlushSync(int32_t put_offset) {
103 return GetErrorState();
104}
105
106int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
107 return PP_FALSE;
108}
109
110PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
111 return PP_FALSE;
112}
113
114PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
115 int* shm_handle,
116 uint32_t* shm_size) {
117 return PP_FALSE;
118}
119
120PP_Graphics3DTrustedState Graphics3D::FlushSyncFast(int32_t put_offset,
121 int32_t last_known_get) {
122 return GetErrorState();
123}
124
125gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
126 return command_buffer_.get();
127}
128
129int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23130 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06131 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28132 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06133 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01134 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06135
[email protected]eeb4e4a2011-07-19 16:22:06136 return PP_OK_COMPLETIONPENDING;
137}
138
[email protected]5c966022011-09-13 18:09:37139PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
140 : InterfaceProxy(dispatcher),
[email protected]0e50fc4d2011-08-01 15:33:51141 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
[email protected]eeb4e4a2011-07-19 16:22:06142}
143
144PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
145}
146
147// static
[email protected]eeb4e4a2011-07-19 16:22:06148PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
149 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06150 PP_Resource share_context,
151 const int32_t* attrib_list) {
152 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
153 if (!dispatcher)
154 return PP_ERROR_BADARGUMENT;
155
[email protected]9ed07f82012-05-29 21:54:55156 HostResource share_host;
157 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
158 if (share_context != 0) {
159 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
160 if (enter.failed())
161 return PP_ERROR_BADARGUMENT;
162
163 PPB_Graphics3D_Shared* share_graphics =
164 static_cast<PPB_Graphics3D_Shared*>(enter.object());
165 share_host = share_graphics->host_resource();
166 share_gles2 = share_graphics->gles2_impl();
167 }
[email protected]eeb4e4a2011-07-19 16:22:06168
169 std::vector<int32_t> attribs;
170 if (attrib_list) {
171 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51172 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
173 attr += 2) {
174 attribs.push_back(attr[0]);
175 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06176 }
[email protected]eeb4e4a2011-07-19 16:22:06177 }
[email protected]0e50fc4d2011-08-01 15:33:51178 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06179
180 HostResource result;
181 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]9ed07f82012-05-29 21:54:55182 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06183 if (result.is_null())
184 return 0;
185
[email protected]51e1aec2011-08-11 04:48:30186 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]9ed07f82012-05-29 21:54:55187 if (!graphics_3d->Init(share_gles2))
[email protected]eeb4e4a2011-07-19 16:22:06188 return 0;
[email protected]7f8b26b2011-08-18 15:41:01189 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06190}
191
192bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
193 bool handled = true;
194 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
196 OnMsgCreate)
197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer,
198 OnMsgInitCommandBuffer)
[email protected]503b3a22011-12-12 23:29:40199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
200 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
202 OnMsgGetState)
203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush,
204 OnMsgFlush)
205 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush,
206 OnMsgAsyncFlush)
207 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
208 OnMsgCreateTransferBuffer)
209 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
210 OnMsgDestroyTransferBuffer)
211 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
212 OnMsgGetTransferBuffer)
213 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
214 OnMsgSwapBuffers)
215
216 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
217 OnMsgSwapBuffersACK)
218 IPC_MESSAGE_UNHANDLED(handled = false)
219
220 IPC_END_MESSAGE_MAP()
221 // FIXME(brettw) handle bad messages!
222 return handled;
223}
224
225void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]9ed07f82012-05-29 21:54:55226 HostResource share_context,
[email protected]eeb4e4a2011-07-19 16:22:06227 const std::vector<int32_t>& attribs,
228 HostResource* result) {
[email protected]0e50fc4d2011-08-01 15:33:51229 if (attribs.empty() || attribs.back() != PP_GRAPHICS3DATTRIB_NONE)
[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
[email protected]eeb4e4a2011-07-19 16:22:06234 if (enter.succeeded()) {
235 result->SetHostResource(
[email protected]9ed07f82012-05-29 21:54:55236 instance,
237 enter.functions()->CreateGraphics3DRaw(instance,
238 share_context.host_resource(),
239 &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06240 }
241}
242
243void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer(
[email protected]503b3a22011-12-12 23:29:40244 const HostResource& context) {
[email protected]eeb4e4a2011-07-19 16:22:06245 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
246 if (enter.failed())
247 return;
248
[email protected]503b3a22011-12-12 23:29:40249 if (!enter.object()->InitCommandBuffer())
[email protected]eeb4e4a2011-07-19 16:22:06250 return;
[email protected]503b3a22011-12-12 23:29:40251}
[email protected]eeb4e4a2011-07-19 16:22:06252
[email protected]503b3a22011-12-12 23:29:40253void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
254 const HostResource& context,
255 int32 transfer_buffer_id) {
256 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
257 if (enter.succeeded())
258 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06259}
260
261void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
[email protected]571b35e82012-05-19 00:04:35262 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]eeb4e4a2011-07-19 16:22:06269 PP_Graphics3DTrustedState pp_state = enter.object()->GetState();
270 *state = GPUStateFromPPState(pp_state);
[email protected]571b35e82012-05-19 00:04:35271 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06272}
273
274void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
275 int32 put_offset,
276 int32 last_known_get,
[email protected]571b35e82012-05-19 00:04:35277 gpu::CommandBuffer::State* state,
278 bool* success) {
[email protected]eeb4e4a2011-07-19 16:22:06279 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
[email protected]571b35e82012-05-19 00:04:35280 if (enter.failed()) {
281 *success = false;
[email protected]eeb4e4a2011-07-19 16:22:06282 return;
[email protected]571b35e82012-05-19 00:04:35283 }
[email protected]eeb4e4a2011-07-19 16:22:06284 PP_Graphics3DTrustedState pp_state = enter.object()->FlushSyncFast(
285 put_offset, last_known_get);
286 *state = GPUStateFromPPState(pp_state);
[email protected]571b35e82012-05-19 00:04:35287 *success = true;
[email protected]eeb4e4a2011-07-19 16:22:06288}
289
290void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
291 int32 put_offset) {
292 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
293 if (enter.succeeded())
294 enter.object()->Flush(put_offset);
295}
296
297void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
298 const HostResource& context,
299 int32 size,
300 int32* id) {
301 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
302 if (enter.succeeded())
303 *id = enter.object()->CreateTransferBuffer(size);
304 else
305 *id = 0;
306}
307
308void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
309 const HostResource& context,
310 int32 id) {
311 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
312 if (enter.succeeded())
313 enter.object()->DestroyTransferBuffer(id);
314}
315
316void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
317 const HostResource& context,
318 int32 id,
319 base::SharedMemoryHandle* transfer_buffer,
320 uint32* size) {
321 *transfer_buffer = base::SharedMemory::NULLHandle();
322 *size = 0;
323
324 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
325 int shm_handle = 0;
326 uint32_t shm_size = 0;
327 if (enter.succeeded() &&
328 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
329 *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
330 *size = shm_size;
331 }
332}
333
334void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40335 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
336 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06337 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06338 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40339 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06340}
341
342void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
343 int32_t pp_error) {
344 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
345 if (enter.succeeded())
346 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
347}
348
349void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
350 int32_t result,
351 const HostResource& context) {
352 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28353 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06354}
355
356} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02357} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06358