Rename GDataSystemService to DriveSystemService
[chromium-blink-merge.git] / ppapi / proxy / ppb_graphics_3d_proxy.cc
blob25bcd44f956e5b725ab13a5f25dbf4000cd2db70
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/proxy/ppb_graphics_3d_proxy.h"
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"
11 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
12 #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"
17 using ppapi::thunk::EnterResourceNoLock;
18 using ppapi::thunk::PPB_Graphics3D_API;
19 using ppapi::thunk::ResourceCreationAPI;
21 namespace ppapi {
22 namespace proxy {
24 namespace {
25 const int32 kCommandBufferSize = 1024 * 1024;
26 const int32 kTransferBufferSize = 1024 * 1024;
28 base::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);
44 PP_Graphics3DTrustedState GetErrorState() {
45 PP_Graphics3DTrustedState error_state = { 0 };
46 error_state.error = PPB_GRAPHICS3D_TRUSTED_ERROR_GENERICERROR;
47 return error_state;
50 gpu::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;
62 } // namespace
64 Graphics3D::Graphics3D(const HostResource& resource)
65 : PPB_Graphics3D_Shared(resource) {
68 Graphics3D::~Graphics3D() {
69 DestroyGLES2Impl();
72 bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
73 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
74 if (!dispatcher)
75 return false;
77 command_buffer_.reset(
78 new PpapiCommandBufferProxy(host_resource(), dispatcher));
79 if (!command_buffer_->Initialize())
80 return false;
82 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
83 share_gles2);
86 PP_Bool Graphics3D::InitCommandBuffer() {
87 return PP_FALSE;
90 PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
91 return PP_FALSE;
94 PP_Graphics3DTrustedState Graphics3D::GetState() {
95 return GetErrorState();
98 PP_Bool Graphics3D::Flush(int32_t put_offset) {
99 return PP_FALSE;
102 PP_Graphics3DTrustedState Graphics3D::FlushSync(int32_t put_offset) {
103 return GetErrorState();
106 int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
107 return PP_FALSE;
110 PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
111 return PP_FALSE;
114 PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
115 int* shm_handle,
116 uint32_t* shm_size) {
117 return PP_FALSE;
120 PP_Graphics3DTrustedState Graphics3D::FlushSyncFast(int32_t put_offset,
121 int32_t last_known_get) {
122 return GetErrorState();
125 gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
126 return command_buffer_.get();
129 int32 Graphics3D::DoSwapBuffers() {
130 gles2_impl()->SwapBuffers();
131 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
132 API_ID_PPB_GRAPHICS_3D, host_resource());
133 msg->set_unblock(true);
134 PluginDispatcher::GetForResource(this)->Send(msg);
136 return PP_OK_COMPLETIONPENDING;
139 PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
140 : InterfaceProxy(dispatcher),
141 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
144 PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
147 // static
148 PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
149 PP_Instance instance,
150 PP_Resource share_context,
151 const int32_t* attrib_list) {
152 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
153 if (!dispatcher)
154 return PP_ERROR_BADARGUMENT;
156 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;
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();
169 std::vector<int32_t> attribs;
170 if (attrib_list) {
171 for (const int32_t* attr = attrib_list;
172 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
173 attr += 2) {
174 attribs.push_back(attr[0]);
175 attribs.push_back(attr[1]);
178 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
180 HostResource result;
181 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
182 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
183 if (result.is_null())
184 return 0;
186 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
187 if (!graphics_3d->Init(share_gles2))
188 return 0;
189 return graphics_3d->GetReference();
192 bool 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)
199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
200 OnMsgSetGetBuffer)
201 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)
216 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
217 OnMsgSwapBuffersACK)
218 IPC_MESSAGE_UNHANDLED(handled = false)
220 IPC_END_MESSAGE_MAP()
221 // FIXME(brettw) handle bad messages!
222 return handled;
225 void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
226 HostResource share_context,
227 const std::vector<int32_t>& attribs,
228 HostResource* result) {
229 if (attribs.empty() || attribs.back() != PP_GRAPHICS3DATTRIB_NONE)
230 return; // Bad message.
232 thunk::EnterResourceCreation enter(instance);
234 if (enter.succeeded()) {
235 result->SetHostResource(
236 instance,
237 enter.functions()->CreateGraphics3DRaw(instance,
238 share_context.host_resource(),
239 &attribs.front()));
243 void PPB_Graphics3D_Proxy::OnMsgInitCommandBuffer(
244 const HostResource& context) {
245 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
246 if (enter.failed())
247 return;
249 if (!enter.object()->InitCommandBuffer())
250 return;
253 void 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);
261 void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
262 gpu::CommandBuffer::State* state,
263 bool* success) {
264 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
265 if (enter.failed()) {
266 *success = false;
267 return;
269 PP_Graphics3DTrustedState pp_state = enter.object()->GetState();
270 *state = GPUStateFromPPState(pp_state);
271 *success = true;
274 void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
275 int32 put_offset,
276 int32 last_known_get,
277 gpu::CommandBuffer::State* state,
278 bool* success) {
279 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
280 if (enter.failed()) {
281 *success = false;
282 return;
284 PP_Graphics3DTrustedState pp_state = enter.object()->FlushSyncFast(
285 put_offset, last_known_get);
286 *state = GPUStateFromPPState(pp_state);
287 *success = true;
290 void 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);
297 void 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;
308 void 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);
316 void 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;
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;
334 void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
335 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
336 context, callback_factory_,
337 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
338 if (enter.succeeded())
339 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
342 void 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);
349 void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
350 int32_t result,
351 const HostResource& context) {
352 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
353 API_ID_PPB_GRAPHICS_3D, context, result));
356 } // namespace proxy
357 } // namespace ppapi