blob: 75f7d83a920b8f36c5e01b90c0f47b9195c3a4ab [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
72bool Graphics3D::Init() {
[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
82 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize);
83}
84
[email protected]503b3a22011-12-12 23:29:4085PP_Bool Graphics3D::InitCommandBuffer() {
[email protected]eeb4e4a2011-07-19 16:22:0686 return PP_FALSE;
87}
88
[email protected]503b3a22011-12-12 23:29:4089PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
[email protected]eeb4e4a2011-07-19 16:22:0690 return PP_FALSE;
91}
92
93PP_Graphics3DTrustedState Graphics3D::GetState() {
94 return GetErrorState();
95}
96
97PP_Bool Graphics3D::Flush(int32_t put_offset) {
98 return PP_FALSE;
99}
100
101PP_Graphics3DTrustedState Graphics3D::FlushSync(int32_t put_offset) {
102 return GetErrorState();
103}
104
105int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
106 return PP_FALSE;
107}
108
109PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
110 return PP_FALSE;
111}
112
113PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
114 int* shm_handle,
115 uint32_t* shm_size) {
116 return PP_FALSE;
117}
118
119PP_Graphics3DTrustedState Graphics3D::FlushSyncFast(int32_t put_offset,
120 int32_t last_known_get) {
121 return GetErrorState();
122}
123
124gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
125 return command_buffer_.get();
126}
127
128int32 Graphics3D::DoSwapBuffers() {
[email protected]561438abd2011-11-24 01:06:23129 gles2_impl()->SwapBuffers();
[email protected]eeb4e4a2011-07-19 16:22:06130 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
[email protected]ac4b54d2011-10-20 23:09:28131 API_ID_PPB_GRAPHICS_3D, host_resource());
[email protected]eeb4e4a2011-07-19 16:22:06132 msg->set_unblock(true);
[email protected]7f8b26b2011-08-18 15:41:01133 PluginDispatcher::GetForResource(this)->Send(msg);
[email protected]eeb4e4a2011-07-19 16:22:06134
[email protected]eeb4e4a2011-07-19 16:22:06135 return PP_OK_COMPLETIONPENDING;
136}
137
[email protected]5c966022011-09-13 18:09:37138PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
139 : InterfaceProxy(dispatcher),
[email protected]0e50fc4d2011-08-01 15:33:51140 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
[email protected]eeb4e4a2011-07-19 16:22:06141}
142
143PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
144}
145
146// static
[email protected]eeb4e4a2011-07-19 16:22:06147PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
148 PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06149 PP_Resource share_context,
150 const int32_t* attrib_list) {
151 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
152 if (!dispatcher)
153 return PP_ERROR_BADARGUMENT;
154
155 // TODO(alokp): Support shared context.
156 DCHECK_EQ(0, share_context);
157 if (share_context != 0)
158 return 0;
159
160 std::vector<int32_t> attribs;
161 if (attrib_list) {
162 for (const int32_t* attr = attrib_list;
[email protected]0e50fc4d2011-08-01 15:33:51163 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
164 attr += 2) {
165 attribs.push_back(attr[0]);
166 attribs.push_back(attr[1]);
[email protected]eeb4e4a2011-07-19 16:22:06167 }
[email protected]eeb4e4a2011-07-19 16:22:06168 }
[email protected]0e50fc4d2011-08-01 15:33:51169 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
[email protected]eeb4e4a2011-07-19 16:22:06170
171 HostResource result;
172 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
[email protected]ac4b54d2011-10-20 23:09:28173 API_ID_PPB_GRAPHICS_3D, instance, attribs, &result));
[email protected]eeb4e4a2011-07-19 16:22:06174 if (result.is_null())
175 return 0;
176
[email protected]51e1aec2011-08-11 04:48:30177 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
[email protected]eeb4e4a2011-07-19 16:22:06178 if (!graphics_3d->Init())
179 return 0;
[email protected]7f8b26b2011-08-18 15:41:01180 return graphics_3d->GetReference();
[email protected]eeb4e4a2011-07-19 16:22:06181}
182
183bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
184 bool handled = true;
185 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
186 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
187 OnMsgCreate)
188 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InitCommandBuffer,
189 OnMsgInitCommandBuffer)
[email protected]503b3a22011-12-12 23:29:40190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
191 OnMsgSetGetBuffer)
[email protected]eeb4e4a2011-07-19 16:22:06192 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
193 OnMsgGetState)
194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush,
195 OnMsgFlush)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush,
197 OnMsgAsyncFlush)
198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
199 OnMsgCreateTransferBuffer)
200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
201 OnMsgDestroyTransferBuffer)
202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
203 OnMsgGetTransferBuffer)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
205 OnMsgSwapBuffers)
206
207 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
208 OnMsgSwapBuffersACK)
209 IPC_MESSAGE_UNHANDLED(handled = false)
210
211 IPC_END_MESSAGE_MAP()
212 // FIXME(brettw) handle bad messages!
213 return handled;
214}
215
216void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
[email protected]eeb4e4a2011-07-19 16:22:06217 const std::vector<int32_t>& attribs,
218 HostResource* result) {
[email protected]0e50fc4d2011-08-01 15:33:51219 if (attribs.empty() || attribs.back() != PP_GRAPHICS3DATTRIB_NONE)
[email protected]eeb4e4a2011-07-19 16:22:06220 return; // Bad message.
221
[email protected]5c966022011-09-13 18:09:37222 thunk::EnterResourceCreation enter(instance);
[email protected]eeb4e4a2011-07-19 16:22:06223 if (enter.succeeded()) {
224 result->SetHostResource(
225 instance,
[email protected]9d8fe822011-08-16 21:02:52226 enter.functions()->CreateGraphics3DRaw(instance, 0, &attribs.front()));
[email protected]eeb4e4a2011-07-19 16:22:06227 }
228}
229
230void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer(
[email protected]503b3a22011-12-12 23:29:40231 const HostResource& context) {
[email protected]eeb4e4a2011-07-19 16:22:06232 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
233 if (enter.failed())
234 return;
235
[email protected]503b3a22011-12-12 23:29:40236 if (!enter.object()->InitCommandBuffer())
[email protected]eeb4e4a2011-07-19 16:22:06237 return;
[email protected]503b3a22011-12-12 23:29:40238}
[email protected]eeb4e4a2011-07-19 16:22:06239
[email protected]503b3a22011-12-12 23:29:40240void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
241 const HostResource& context,
242 int32 transfer_buffer_id) {
243 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
244 if (enter.succeeded())
245 enter.object()->SetGetBuffer(transfer_buffer_id);
[email protected]eeb4e4a2011-07-19 16:22:06246}
247
248void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
249 gpu::CommandBuffer::State* state) {
250 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
251 if (enter.failed())
252 return;
253 PP_Graphics3DTrustedState pp_state = enter.object()->GetState();
254 *state = GPUStateFromPPState(pp_state);
255}
256
257void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
258 int32 put_offset,
259 int32 last_known_get,
260 gpu::CommandBuffer::State* state) {
261 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
262 if (enter.failed())
263 return;
264 PP_Graphics3DTrustedState pp_state = enter.object()->FlushSyncFast(
265 put_offset, last_known_get);
266 *state = GPUStateFromPPState(pp_state);
267}
268
269void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
270 int32 put_offset) {
271 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
272 if (enter.succeeded())
273 enter.object()->Flush(put_offset);
274}
275
276void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
277 const HostResource& context,
278 int32 size,
279 int32* id) {
280 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
281 if (enter.succeeded())
282 *id = enter.object()->CreateTransferBuffer(size);
283 else
284 *id = 0;
285}
286
287void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
288 const HostResource& context,
289 int32 id) {
290 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
291 if (enter.succeeded())
292 enter.object()->DestroyTransferBuffer(id);
293}
294
295void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
296 const HostResource& context,
297 int32 id,
298 base::SharedMemoryHandle* transfer_buffer,
299 uint32* size) {
300 *transfer_buffer = base::SharedMemory::NULLHandle();
301 *size = 0;
302
303 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
304 int shm_handle = 0;
305 uint32_t shm_size = 0;
306 if (enter.succeeded() &&
307 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
308 *transfer_buffer = TransportSHMHandleFromInt(dispatcher(), shm_handle);
309 *size = shm_size;
310 }
311}
312
313void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
[email protected]79d23c72011-08-08 19:40:40314 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
315 context, callback_factory_,
[email protected]eeb4e4a2011-07-19 16:22:06316 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
[email protected]eeb4e4a2011-07-19 16:22:06317 if (enter.succeeded())
[email protected]79d23c72011-08-08 19:40:40318 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
[email protected]eeb4e4a2011-07-19 16:22:06319}
320
321void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
322 int32_t pp_error) {
323 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
324 if (enter.succeeded())
325 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
326}
327
328void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
329 int32_t result,
330 const HostResource& context) {
331 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
[email protected]ac4b54d2011-10-20 23:09:28332 API_ID_PPB_GRAPHICS_3D, context, result));
[email protected]eeb4e4a2011-07-19 16:22:06333}
334
335} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02336} // namespace ppapi
[email protected]eeb4e4a2011-07-19 16:22:06337