Don't announce clipboard events if the event target is not visible and focused.
[chromium-blink-merge.git] / ppapi / proxy / ppb_graphics_3d_proxy.cc
blob6b49914c2724d2a10c97fa0aec5a37d326138e7b
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 base::PlatformFile source = IPC::PlatformFileForTransitToPlatformFile(handle);
37 // Don't close the handle, it doesn't belong to us.
38 return dispatcher->ShareHandleWithRemote(source, false);
40 #endif // !defined(OS_NACL)
42 gpu::CommandBuffer::State GetErrorState() {
43 gpu::CommandBuffer::State error_state;
44 error_state.error = gpu::error::kGenericError;
45 return error_state;
48 } // namespace
50 Graphics3D::Graphics3D(const HostResource& resource)
51 : PPB_Graphics3D_Shared(resource) {
54 Graphics3D::~Graphics3D() {
55 DestroyGLES2Impl();
58 bool Graphics3D::Init(gpu::gles2::GLES2Implementation* share_gles2,
59 const gpu::Capabilities& capabilities,
60 const SerializedHandle& shared_state) {
61 PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
62 if (!dispatcher)
63 return false;
65 command_buffer_.reset(new PpapiCommandBufferProxy(
66 host_resource(), dispatcher, capabilities, shared_state));
68 return CreateGLES2Impl(kCommandBufferSize, kTransferBufferSize,
69 share_gles2);
72 PP_Bool Graphics3D::SetGetBuffer(int32_t /* transfer_buffer_id */) {
73 return PP_FALSE;
76 PP_Bool Graphics3D::Flush(int32_t put_offset) {
77 return PP_FALSE;
80 scoped_refptr<gpu::Buffer> Graphics3D::CreateTransferBuffer(
81 uint32_t size,
82 int32_t* id) {
83 *id = -1;
84 return NULL;
87 PP_Bool Graphics3D::DestroyTransferBuffer(int32_t id) {
88 return PP_FALSE;
91 gpu::CommandBuffer::State Graphics3D::WaitForTokenInRange(int32_t start,
92 int32_t end) {
93 return GetErrorState();
96 gpu::CommandBuffer::State Graphics3D::WaitForGetOffsetInRange(int32_t start,
97 int32_t end) {
98 return GetErrorState();
101 uint32_t Graphics3D::InsertSyncPoint() {
102 NOTREACHED();
103 return 0;
106 uint32_t Graphics3D::InsertFutureSyncPoint() {
107 NOTREACHED();
108 return 0;
111 void Graphics3D::RetireSyncPoint(uint32_t sync_point) {
112 NOTREACHED();
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 gpu::Capabilities capabilities;
176 ppapi::proxy::SerializedHandle shared_state;
177 dispatcher->Send(new PpapiHostMsg_PPBGraphics3D_Create(API_ID_PPB_GRAPHICS_3D,
178 instance, share_host, attribs, &result, &capabilities, &shared_state));
180 if (result.is_null())
181 return 0;
183 scoped_refptr<Graphics3D> graphics_3d(new Graphics3D(result));
184 if (!graphics_3d->Init(share_gles2, capabilities, shared_state))
185 return 0;
186 return graphics_3d->GetReference();
189 bool PPB_Graphics3D_Proxy::OnMessageReceived(const IPC::Message& msg) {
190 bool handled = true;
191 IPC_BEGIN_MESSAGE_MAP(PPB_Graphics3D_Proxy, msg)
192 #if !defined(OS_NACL)
193 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_Create,
194 OnMsgCreate)
195 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SetGetBuffer,
196 OnMsgSetGetBuffer)
197 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForTokenInRange,
198 OnMsgWaitForTokenInRange)
199 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_WaitForGetOffsetInRange,
200 OnMsgWaitForGetOffsetInRange)
201 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_AsyncFlush, OnMsgAsyncFlush)
202 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_CreateTransferBuffer,
203 OnMsgCreateTransferBuffer)
204 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_DestroyTransferBuffer,
205 OnMsgDestroyTransferBuffer)
206 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_SwapBuffers,
207 OnMsgSwapBuffers)
208 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertSyncPoint,
209 OnMsgInsertSyncPoint)
210 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_InsertFutureSyncPoint,
211 OnMsgInsertFutureSyncPoint)
212 IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBGraphics3D_RetireSyncPoint,
213 OnMsgRetireSyncPoint)
214 #endif // !defined(OS_NACL)
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 #if !defined(OS_NACL)
226 void PPB_Graphics3D_Proxy::OnMsgCreate(PP_Instance instance,
227 HostResource share_context,
228 const std::vector<int32_t>& attribs,
229 HostResource* result,
230 gpu::Capabilities* capabilities,
231 SerializedHandle* shared_state) {
232 shared_state->set_null_shmem();
233 if (attribs.empty() ||
234 attribs.back() != PP_GRAPHICS3DATTRIB_NONE ||
235 !(attribs.size() & 1))
236 return; // Bad message.
238 thunk::EnterResourceCreation enter(instance);
240 if (!enter.succeeded())
241 return;
243 base::SharedMemoryHandle handle = IPC::InvalidPlatformFileForTransit();
244 result->SetHostResource(
245 instance,
246 enter.functions()->CreateGraphics3DRaw(instance,
247 share_context.host_resource(),
248 &attribs.front(),
249 capabilities,
250 &handle));
251 if (!result->is_null()) {
252 shared_state->set_shmem(TransportSHMHandle(dispatcher(), handle),
253 sizeof(gpu::CommandBuffer::State));
257 void PPB_Graphics3D_Proxy::OnMsgSetGetBuffer(
258 const HostResource& context,
259 int32 transfer_buffer_id) {
260 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
261 if (enter.succeeded())
262 enter.object()->SetGetBuffer(transfer_buffer_id);
265 void PPB_Graphics3D_Proxy::OnMsgWaitForTokenInRange(
266 const HostResource& context,
267 int32 start,
268 int32 end,
269 gpu::CommandBuffer::State* state,
270 bool* success) {
271 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
272 if (enter.failed()) {
273 *success = false;
274 return;
276 *state = enter.object()->WaitForTokenInRange(start, end);
277 *success = true;
280 void PPB_Graphics3D_Proxy::OnMsgWaitForGetOffsetInRange(
281 const HostResource& context,
282 int32 start,
283 int32 end,
284 gpu::CommandBuffer::State* state,
285 bool* success) {
286 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
287 if (enter.failed()) {
288 *success = false;
289 return;
291 *state = enter.object()->WaitForGetOffsetInRange(start, end);
292 *success = true;
295 void PPB_Graphics3D_Proxy::OnMsgAsyncFlush(const HostResource& context,
296 int32 put_offset) {
297 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
298 if (enter.succeeded())
299 enter.object()->Flush(put_offset);
302 void PPB_Graphics3D_Proxy::OnMsgCreateTransferBuffer(
303 const HostResource& context,
304 uint32 size,
305 int32* id,
306 SerializedHandle* transfer_buffer) {
307 transfer_buffer->set_null_shmem();
308 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
309 if (enter.succeeded()) {
310 scoped_refptr<gpu::Buffer> buffer =
311 enter.object()->CreateTransferBuffer(size, id);
312 if (!buffer.get())
313 return;
314 gpu::SharedMemoryBufferBacking* backing =
315 static_cast<gpu::SharedMemoryBufferBacking*>(buffer->backing());
316 DCHECK(backing && backing->shared_memory());
317 transfer_buffer->set_shmem(
318 TransportSHMHandle(dispatcher(), backing->shared_memory()->handle()),
319 base::checked_cast<uint32_t>(buffer->size()));
320 } else {
321 *id = -1;
325 void PPB_Graphics3D_Proxy::OnMsgDestroyTransferBuffer(
326 const HostResource& context,
327 int32 id) {
328 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
329 if (enter.succeeded())
330 enter.object()->DestroyTransferBuffer(id);
333 void PPB_Graphics3D_Proxy::OnMsgSwapBuffers(const HostResource& context) {
334 EnterHostFromHostResourceForceCallback<PPB_Graphics3D_API> enter(
335 context, callback_factory_,
336 &PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin, context);
337 if (enter.succeeded())
338 enter.SetResult(enter.object()->SwapBuffers(enter.callback()));
341 void PPB_Graphics3D_Proxy::OnMsgInsertSyncPoint(const HostResource& context,
342 uint32* sync_point) {
343 *sync_point = 0;
344 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
345 if (enter.succeeded())
346 *sync_point = enter.object()->InsertSyncPoint();
349 void PPB_Graphics3D_Proxy::OnMsgInsertFutureSyncPoint(
350 const HostResource& context,
351 uint32* sync_point) {
352 *sync_point = 0;
353 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
354 if (enter.succeeded())
355 *sync_point = enter.object()->InsertFutureSyncPoint();
358 void PPB_Graphics3D_Proxy::OnMsgRetireSyncPoint(const HostResource& context,
359 uint32 sync_point) {
360 EnterHostFromHostResource<PPB_Graphics3D_API> enter(context);
361 if (enter.succeeded())
362 enter.object()->RetireSyncPoint(sync_point);
364 #endif // !defined(OS_NACL)
366 void PPB_Graphics3D_Proxy::OnMsgSwapBuffersACK(const HostResource& resource,
367 int32_t pp_error) {
368 EnterPluginFromHostResource<PPB_Graphics3D_API> enter(resource);
369 if (enter.succeeded())
370 static_cast<Graphics3D*>(enter.object())->SwapBuffersACK(pp_error);
373 #if !defined(OS_NACL)
374 void PPB_Graphics3D_Proxy::SendSwapBuffersACKToPlugin(
375 int32_t result,
376 const HostResource& context) {
377 dispatcher()->Send(new PpapiMsg_PPBGraphics3D_SwapBuffersACK(
378 API_ID_PPB_GRAPHICS_3D, context, result));
380 #endif // !defined(OS_NACL)
382 } // namespace proxy
383 } // namespace ppapi