Add git cl format presubmit warning for extension and apps.
[chromium-blink-merge.git] / ppapi / proxy / ppb_graphics_3d_proxy.cc
blob02e06f76b8fff4677e5637335a6cf08683fa1d81
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 "gpu/command_buffer/common/command_buffer.h"
9 #include "ppapi/c/pp_errors.h"
10 #include "ppapi/proxy/enter_proxy.h"
11 #include "ppapi/proxy/plugin_dispatcher.h"
12 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
13 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/shared_impl/ppapi_globals.h"
15 #include "ppapi/thunk/enter.h"
16 #include "ppapi/thunk/resource_creation_api.h"
17 #include "ppapi/thunk/thunk.h"
19 using ppapi::thunk::EnterResourceNoLock;
20 using ppapi::thunk::PPB_Graphics3D_API;
21 using ppapi::thunk::ResourceCreationAPI;
23 namespace ppapi {
24 namespace proxy {
26 namespace {
28 const int32 kCommandBufferSize = 1024 * 1024;
29 const int32 kTransferBufferSize = 1024 * 1024;
31 base::SharedMemoryHandle TransportSHMHandleFromInt(Dispatcher* dispatcher,
32 int shm_handle) {
33 // TODO(piman): Change trusted interface to return a PP_FileHandle, those
34 // casts are ugly.
35 base::PlatformFile source =
36 #if defined(OS_WIN)
37 reinterpret_cast<HANDLE>(static_cast<intptr_t>(shm_handle));
38 #elif defined(OS_POSIX)
39 shm_handle;
40 #else
41 #error Not implemented.
42 #endif
43 // Don't close the handle, it doesn't belong to us.
44 return dispatcher->ShareHandleWithRemote(source, false);
47 gpu::CommandBuffer::State GetErrorState() {
48 gpu::CommandBuffer::State error_state;
49 error_state.error = gpu::error::kGenericError;
50 return error_state;
53 } // namespace
55 Graphics3D::Graphics3D(const HostResource& resource)
56 : PPB_Graphics3D_Shared(resource) {
59 Graphics3D::~Graphics3D() {
60 DestroyGLES2Impl();
63 bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2) {
64 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
65 if (!dispatcher)
66 return false;
68 command_buffer_.reset(
69 new PpapiCommandBufferProxy(host_resource(), dispatcher));
71 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
72 share_gles2);
75 PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
76 return PP_FALSE;
79 gpu::CommandBuffer::State Graphics3D::GetState() {
80 return GetErrorState();
83 PP_Bool Graphics3D::Flush(int32_t put_offset) {
84 return PP_FALSE;
87 gpu::CommandBuffer::State Graphics3D::FlushSync(int32_t put_offset) {
88 return GetErrorState();
91 int32_t Graphics3D::CreateTransferBuffer(uint32_t size) {
92 return PP_FALSE;
95 PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
96 return PP_FALSE;
99 PP_Bool Graphics3D::GetTransferBuffer(int32_t id,
100 int* shm_handle,
101 uint32_t* shm_size) {
102 return PP_FALSE;
105 gpu::CommandBuffer::State Graphics3D::FlushSyncFast(int32_t put_offset,
106 int32_t last_known_get) {
107 return GetErrorState();
110 uint32_t Graphics3D::InsertSyncPoint() {
111 NOTREACHED();
112 return 0;
115 gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
116 return command_buffer_.get();
119 gpu::GpuControl* Graphics3D::GetGpuControl() {
120 return command_buffer_.get();
123 int32 Graphics3D::DoSwapBuffers() {
124 gles2_impl()->SwapBuffers();
125 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
126 API_ID_PPB_GRAPHICS_3D, host_resource());
127 msg->set_unblock(true);
128 PluginDispatcher::GetForResource(this)->Send(msg);
130 return PP_OK_COMPLETIONPENDING;
133 PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
134 : InterfaceProxy(dispatcher),
135 callback_factory_(this) {
138 PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
141 // static
142 PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
143 PP_Instance instance,
144 PP_Resource share_context,
145 const int32_t* attrib_list) {
146 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
147 if (!dispatcher)
148 return PP_ERROR_BADARGUMENT;
150 HostResource share_host;
151 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
152 if (share_context != 0) {
153 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
154 if (enter.failed())
155 return PP_ERROR_BADARGUMENT;
157 PPB_Graphics3D_Shared* share_graphics =
158 static_cast<PPB_Graphics3D_Shared*>(enter.object());
159 share_host = share_graphics->host_resource();
160 share_gles2 = share_graphics->gles2_impl();
163 std::vector<int32_t> attribs;
164 if (attrib_list) {
165 for (const int32_t* attr = attrib_list;
166 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
167 attr += 2) {
168 attribs.push_back(attr[0]);
169 attribs.push_back(attr[1]);
172 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
174 HostResource result;
175 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(
176 API_ID_PPB_GRAPHICS_3D, instance, share_host, attribs, &result));
177 if (result.is_null())
178 return 0;
180 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
181 if (!graphics_3d->Init(share_gles2))
182 return 0;
183 return graphics_3d->GetReference();
186 bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
187 bool handled = true;
188 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
189 #if !defined(OS_NACL)
190 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
191 OnMsgCreate)
192 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
193 OnMsgSetGetBuffer)
194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetState,
195 OnMsgGetState)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Flush,
197 OnMsgFlush)
198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush,
199 OnMsgAsyncFlush)
200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
201 OnMsgCreateTransferBuffer)
202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
203 OnMsgDestroyTransferBuffer)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_GetTransferBuffer,
205 OnMsgGetTransferBuffer)
206 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
207 OnMsgSwapBuffers)
208 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
209 OnMsgInsertSyncPoint)
210 #endif // !defined(OS_NACL)
212 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
213 OnMsgSwapBuffersACK)
214 IPC_MESSAGE_UNHANDLED(handled = false)
216 IPC_END_MESSAGE_MAP()
217 // FIXME(brettw) handle bad messages!
218 return handled;
221 #if !defined(OS_NACL)
222 void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
223 HostResource share_context,
224 const std::vector<int32_t>& attribs,
225 HostResource* result) {
226 if (attribs.empty() ||
227 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
228 !(attribs.size() & 1))
229 return; // Bad message.
231 thunk::EnterResourceCreation enter(instance);
233 if (enter.succeeded()) {
234 result->SetHostResource(
235 instance,
236 enter.functions()->CreateGraphics3DRaw(instance,
237 share_context.host_resource(),
238 &attribs.front()));
242 void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
243 const HostResource& context,
244 int32 transfer_buffer_id) {
245 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
246 if (enter.succeeded())
247 enter.object()->SetGetBuffer(transfer_buffer_id);
250 void PPB_Graphics3D_Proxy::OnMsgGetState(const HostResource& context,
251 gpu::CommandBuffer::State* state,
252 bool* success) {
253 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
254 if (enter.failed()) {
255 *success = false;
256 return;
258 *state = enter.object()->GetState();
259 *success = true;
262 void PPB_Graphics3D_Proxy::OnMsgFlush(const HostResource& context,
263 int32 put_offset,
264 int32 last_known_get,
265 gpu::CommandBuffer::State* state,
266 bool* success) {
267 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
268 if (enter.failed()) {
269 *success = false;
270 return;
272 *state = enter.object()->FlushSyncFast(put_offset, last_known_get);
273 *success = true;
276 void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
277 int32 put_offset) {
278 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
279 if (enter.succeeded())
280 enter.object()->Flush(put_offset);
283 void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
284 const HostResource& context,
285 uint32 size,
286 int32* id) {
287 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
288 if (enter.succeeded())
289 *id = enter.object()->CreateTransferBuffer(size);
290 else
291 *id = -1;
294 void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
295 const HostResource& context,
296 int32 id) {
297 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
298 if (enter.succeeded())
299 enter.object()->DestroyTransferBuffer(id);
302 void PPB_Graphics3D_Proxy::OnMsgGetTransferBuffer(
303 const HostResource& context,
304 int32 id,
305 ppapi::proxy::SerializedHandle* transfer_buffer) {
306 transfer_buffer->set_null_shmem();
308 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
309 int shm_handle = 0;
310 uint32_t shm_size = 0;
311 if (enter.succeeded() &&
312 enter.object()->GetTransferBuffer(id, &shm_handle, &shm_size)) {
313 transfer_buffer->set_shmem(
314 TransportSHMHandleFromInt(dispatcher(), shm_handle),
315 shm_size);
319 void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
320 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
321 context, callback_factory_,
322 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
323 if (enter.succeeded())
324 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
327 void 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();
334 #endif // !defined(OS_NACL)
336 void 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);
343 #if !defined(OS_NACL)
344 void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
345 int32_t result,
346 const HostResource& context) {
347 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
348 API_ID_PPB_GRAPHICS_3D, context, result));
350 #endif // !defined(OS_NACL)
352 } // namespace proxy
353 } // namespace ppapi