Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ppapi / proxy / ppb_graphics_3d_proxy.cc
blob8a8c6b7f4d3746f43b06befe10448fd26983e7e4
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 "base/numerics/safe_conversions.h"
8 #include "gpu/command_buffer/client/gles2_implementation.h"
9 #include "gpu/command_buffer/common/command_buffer.h"
10 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/proxy/enter_proxy.h"
12 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/ppapi_command_buffer_proxy.h"
14 #include "ppapi/proxy/ppapi_messages.h"
15 #include "ppapi/shared_impl/ppapi_globals.h"
16 #include "ppapi/thunk/enter.h"
17 #include "ppapi/thunk/resource_creation_api.h"
18 #include "ppapi/thunk/thunk.h"
20 using ppapi::thunk::EnterResourceNoLock;
21 using ppapi::thunk::PPB_Graphics3D_API;
22 using ppapi::thunk::ResourceCreationAPI;
24 namespace ppapi {
25 namespace proxy {
27 namespace {
29 const int32 kCommandBufferSize = 1024 * 1024;
30 const int32 kTransferBufferSize = 1024 * 1024;
32 #if !defined(OS_NACL)
33 base::SharedMemoryHandle TransportSHMHandle(
34 Dispatcher* dispatcher,
35 const base::SharedMemoryHandle& handle) {
36 // Don't close the handle, it doesn't belong to us.
37 return dispatcher->ShareSharedMemoryHandleWithRemote(handle);
39 #endif // !defined(OS_NACL)
41 gpu::CommandBuffer::State GetErrorState() {
42 gpu::CommandBuffer::State error_state;
43 error_state.error = gpu::error::kGenericError;
44 return error_state;
47 } // namespace
49 Graphics3D::Graphics3D(const HostResource& resource)
50 : PPB_Graphics3D_Shared(resource) {
53 Graphics3D::~Graphics3D() {
54 DestroyGLES2Impl();
57 bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2,
58 const gpu::Capabilities& capabilities,
59 const SerializedHandle& shared_state) {
60 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
61 if (!dispatcher)
62 return false;
64 command_buffer_.reset(new PpapiCommandBufferProxy(
65 host_resource(), dispatcher, capabilities, shared_state));
67 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
68 share_gles2);
71 PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
72 return PP_FALSE;
75 PP_Bool Graphics3D::Flush(int32_t put_offset) {
76 return PP_FALSE;
79 scoped_refptr<gpu::Buffer> Graphics3D::CreateTransferBuffer(
80 uint32_t size,
81 int32_t* id) {
82 *id = -1;
83 return NULL;
86 PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
87 return PP_FALSE;
90 gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
91 int32_t end) {
92 return GetErrorState();
95 gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
96 int32_t end) {
97 return GetErrorState();
100 uint32_t Graphics3D::InsertSyncPoint() {
101 NOTREACHED();
102 return 0;
105 uint32_t Graphics3D::InsertFutureSyncPoint() {
106 NOTREACHED();
107 return 0;
110 void Graphics3D::RetireSyncPoint(uint32_t sync_point) {
111 NOTREACHED();
114 gpu::CommandBuffer* Graphics3D::GetCommandBuffer() {
115 return command_buffer_.get();
118 gpu::GpuControl* Graphics3D::GetGpuControl() {
119 return command_buffer_.get();
122 int32 Graphics3D::DoSwapBuffers() {
123 gles2_impl()->SwapBuffers();
124 IPC::Message* msg = new PpapiHostMsg_PPBGraphics3D_SwapBuffers(
125 API_ID_PPB_GRAPHICS_3D, host_resource());
126 msg->set_unblock(true);
127 PluginDispatcher::GetForResource(this)->Send(msg);
129 return PP_OK_COMPLETIONPENDING;
132 PPB_Graphics3D_Proxy::PPB_Graphics3D_Proxy(Dispatcher* dispatcher)
133 : InterfaceProxy(dispatcher),
134 callback_factory_(this) {
137 PPB_Graphics3D_Proxy::~PPB_Graphics3D_Proxy() {
140 // static
141 PP_Resource PPB_Graphics3D_Proxy::CreateProxyResource(
142 PP_Instance instance,
143 PP_Resource share_context,
144 const int32_t* attrib_list) {
145 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
146 if (!dispatcher)
147 return PP_ERROR_BADARGUMENT;
149 HostResource share_host;
150 gpu::gles2::GLES2Implementation* share_gles2 = NULL;
151 if (share_context != 0) {
152 EnterResourceNoLock<PPB_Graphics3D_API> enter(share_context, true);
153 if (enter.failed())
154 return PP_ERROR_BADARGUMENT;
156 PPB_Graphics3D_Shared* share_graphics =
157 static_cast<PPB_Graphics3D_Shared*>(enter.object());
158 share_host = share_graphics->host_resource();
159 share_gles2 = share_graphics->gles2_impl();
162 std::vector<int32_t> attribs;
163 if (attrib_list) {
164 for (const int32_t* attr = attrib_list;
165 attr[0] != PP_GRAPHICS3DATTRIB_NONE;
166 attr += 2) {
167 attribs.push_back(attr[0]);
168 attribs.push_back(attr[1]);
171 attribs.push_back(PP_GRAPHICS3DATTRIB_NONE);
173 HostResource result;
174 gpu::Capabilities capabilities;
175 ppapi::proxy::SerializedHandle shared_state;
176 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(API_ID_PPB_GRAPHICS_3D,
177 instance, share_host, attribs, &result, &capabilities, &shared_state));
179 if (result.is_null())
180 return 0;
182 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
183 if (!graphics_3d->Init(share_gles2, capabilities, shared_state))
184 return 0;
185 return graphics_3d->GetReference();
188 bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
189 bool handled = true;
190 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
191 #if !defined(OS_NACL)
192 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
193 OnMsgCreate)
194 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
195 OnMsgSetGetBuffer)
196 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
197 OnMsgWaitForTokenInRange)
198 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
199 OnMsgWaitForGetOffsetInRange)
200 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
202 OnMsgCreateTransferBuffer)
203 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
204 OnMsgDestroyTransferBuffer)
205 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
206 OnMsgSwapBuffers)
207 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
208 OnMsgInsertSyncPoint)
209 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint,
210 OnMsgInsertFutureSyncPoint)
211 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_RetireSyncPoint,
212 OnMsgRetireSyncPoint)
213 #endif // !defined(OS_NACL)
215 IPC_MESSAGE_HANDLER(PpapiMsg_PPBGraphics3D_SwapBuffersACK,
216 OnMsgSwapBuffersACK)
217 IPC_MESSAGE_UNHANDLED(handled = false)
219 IPC_END_MESSAGE_MAP()
220 // FIXME(brettw) handle bad messages!
221 return handled;
224 #if !defined(OS_NACL)
225 void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
226 HostResource share_context,
227 const std::vector<int32_t>& attribs,
228 HostResource* result,
229 gpu::Capabilities* capabilities,
230 SerializedHandle* shared_state) {
231 shared_state->set_null_shmem();
232 if (attribs.empty() ||
233 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
234 !(attribs.size() & 1))
235 return; // Bad message.
237 thunk::EnterResourceCreation enter(instance);
239 if (!enter.succeeded())
240 return;
242 base::SharedMemoryHandle handle = base::SharedMemory::NULLHandle();
243 result->SetHostResource(
244 instance,
245 enter.functions()->CreateGraphics3DRaw(instance,
246 share_context.host_resource(),
247 &attribs.front(),
248 capabilities,
249 &handle));
250 if (!result->is_null()) {
251 shared_state->set_shmem(TransportSHMHandle(dispatcher(), handle),
252 sizeof(gpu::CommandBuffer::State));
256 void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
257 const HostResource& context,
258 int32 transfer_buffer_id) {
259 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
260 if (enter.succeeded())
261 enter.object()->SetGetBuffer(transfer_buffer_id);
264 void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
265 const HostResource& context,
266 int32 start,
267 int32 end,
268 gpu::CommandBuffer::State* state,
269 bool* success) {
270 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
271 if (enter.failed()) {
272 *success = false;
273 return;
275 *state = enter.object()->WaitForTokenInRange(start, end);
276 *success = true;
279 void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
280 const HostResource& context,
281 int32 start,
282 int32 end,
283 gpu::CommandBuffer::State* state,
284 bool* success) {
285 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
286 if (enter.failed()) {
287 *success = false;
288 return;
290 *state = enter.object()->WaitForGetOffsetInRange(start, end);
291 *success = true;
294 void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
295 int32 put_offset) {
296 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
297 if (enter.succeeded())
298 enter.object()->Flush(put_offset);
301 void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
302 const HostResource& context,
303 uint32 size,
304 int32* id,
305 SerializedHandle* transfer_buffer) {
306 transfer_buffer->set_null_shmem();
307 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
308 if (enter.succeeded()) {
309 scoped_refptr<gpu::Buffer> buffer =
310 enter.object()->CreateTransferBuffer(size, id);
311 if (!buffer.get())
312 return;
313 gpu::SharedMemoryBufferBacking* backing =
314 static_cast<gpu::SharedMemoryBufferBacking*>(buffer->backing());
315 DCHECK(backing && backing->shared_memory());
316 transfer_buffer->set_shmem(
317 TransportSHMHandle(dispatcher(), backing->shared_memory()->handle()),
318 base::checked_cast<uint32_t>(buffer->size()));
319 } else {
320 *id = -1;
324 void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
325 const HostResource& context,
326 int32 id) {
327 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
328 if (enter.succeeded())
329 enter.object()->DestroyTransferBuffer(id);
332 void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
333 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
334 context, callback_factory_,
335 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
336 if (enter.succeeded())
337 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
340 void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
341 uint32* sync_point) {
342 *sync_point = 0;
343 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
344 if (enter.succeeded())
345 *sync_point = enter.object()->InsertSyncPoint();
348 void PPB_Graphics3D_Proxy::OnMsgInsertFutureSyncPoint(
349 const HostResource& context,
350 uint32* sync_point) {
351 *sync_point = 0;
352 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
353 if (enter.succeeded())
354 *sync_point = enter.object()->InsertFutureSyncPoint();
357 void PPB_Graphics3D_Proxy::OnMsgRetireSyncPoint(const HostResource& context,
358 uint32 sync_point) {
359 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
360 if (enter.succeeded())
361 enter.object()->RetireSyncPoint(sync_point);
363 #endif // !defined(OS_NACL)
365 void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
366 int32_t pp_error) {
367 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
368 if (enter.succeeded())
369 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
372 #if !defined(OS_NACL)
373 void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
374 int32_t result,
375 const HostResource& context) {
376 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
377 API_ID_PPB_GRAPHICS_3D, context, result));
379 #endif // !defined(OS_NACL)
381 } // namespace proxy
382 } // namespace ppapi