OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/gpu_process_host.h" | 5 #include "chrome/browser/gpu_process_host.h" |
6 | 6 |
7 #include "app/app_switches.h" | 7 #include "app/app_switches.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/string_piece.h" | 11 #include "base/string_piece.h" |
12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
13 #include "chrome/browser/browser_thread.h" | 13 #include "chrome/browser/browser_thread.h" |
14 #include "chrome/browser/gpu_blacklist.h" | 14 #include "chrome/browser/gpu_blacklist.h" |
15 #include "chrome/browser/gpu_process_host_ui_shim.h" | 15 #include "chrome/browser/gpu_process_host_ui_shim.h" |
16 #include "chrome/browser/renderer_host/render_message_filter.h" | 16 #include "chrome/browser/renderer_host/render_message_filter.h" |
17 #include "chrome/browser/renderer_host/render_view_host.h" | |
18 #include "chrome/browser/renderer_host/render_widget_host_view.h" | |
19 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" | 17 #include "chrome/browser/tab_contents/render_view_host_delegate_helper.h" |
20 #include "chrome/common/chrome_switches.h" | 18 #include "chrome/common/chrome_switches.h" |
21 #include "chrome/common/gpu_feature_flags.h" | 19 #include "chrome/common/gpu_feature_flags.h" |
22 #include "chrome/common/gpu_info.h" | 20 #include "chrome/common/gpu_info.h" |
23 #include "chrome/common/gpu_messages.h" | 21 #include "chrome/common/gpu_messages.h" |
24 #include "chrome/common/render_messages.h" | 22 #include "chrome/common/render_messages.h" |
25 #include "chrome/gpu/gpu_thread.h" | 23 #include "chrome/gpu/gpu_thread.h" |
26 #include "grit/browser_resources.h" | 24 #include "grit/browser_resources.h" |
27 #include "ipc/ipc_channel_handle.h" | 25 #include "ipc/ipc_channel_handle.h" |
28 #include "ipc/ipc_switches.h" | 26 #include "ipc/ipc_switches.h" |
29 #include "media/base/media_switches.h" | 27 #include "media/base/media_switches.h" |
30 | 28 |
31 #if defined(OS_LINUX) | |
32 // These two #includes need to come after render_messages.h. | |
33 #include <gdk/gdkwindow.h> // NOLINT | |
34 #include <gdk/gdkx.h> // NOLINT | |
35 #include "gfx/gtk_native_view_id_manager.h" | |
36 #include "gfx/size.h" | |
37 #include "ui/base/x/x11_util.h" | |
38 #endif // defined(OS_LINUX) | |
39 | |
40 namespace { | 29 namespace { |
41 | 30 |
42 enum GPUBlacklistTestResult { | 31 enum GPUBlacklistTestResult { |
43 BLOCKED, | 32 BLOCKED, |
44 ALLOWED, | 33 ALLOWED, |
45 BLACKLIST_TEST_RESULT_MAX | 34 BLACKLIST_TEST_RESULT_MAX |
46 }; | 35 }; |
47 | 36 |
48 enum GPUProcessLifetimeEvent { | 37 enum GPUProcessLifetimeEvent { |
49 LAUNCED, | 38 LAUNCED, |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 } | 207 } |
219 | 208 |
220 GpuProcessHost::SynchronizationRequest::~SynchronizationRequest() {} | 209 GpuProcessHost::SynchronizationRequest::~SynchronizationRequest() {} |
221 | 210 |
222 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { | 211 bool GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { |
223 DCHECK(CalledOnValidThread()); | 212 DCHECK(CalledOnValidThread()); |
224 | 213 |
225 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) | 214 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) |
226 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) | 215 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) |
227 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) | 216 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) |
228 #if defined(OS_LINUX) | |
229 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_GetViewXID, OnGetViewXID) | |
230 IPC_MESSAGE_HANDLER(GpuHostMsg_ReleaseXID, OnReleaseXID) | |
231 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_ResizeXID, OnResizeXID) | |
232 #elif defined(OS_MACOSX) | |
233 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSetIOSurface, | |
234 OnAcceleratedSurfaceSetIOSurface) | |
235 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped, | |
236 OnAcceleratedSurfaceBuffersSwapped) | |
237 #elif defined(OS_WIN) | |
238 IPC_MESSAGE_HANDLER_DELAY_REPLY(GpuHostMsg_GetCompositorHostWindow, | |
239 OnGetCompositorHostWindow) | |
240 #endif | |
241 // If the IO thread does not handle the message then automatically route it | 217 // If the IO thread does not handle the message then automatically route it |
242 // to the UI thread. The UI thread will report an error if it does not | 218 // to the UI thread. The UI thread will report an error if it does not |
243 // handle it. | 219 // handle it. |
244 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) | 220 IPC_MESSAGE_UNHANDLED(RouteOnUIThread(message)) |
245 IPC_END_MESSAGE_MAP() | 221 IPC_END_MESSAGE_MAP() |
246 | 222 |
247 return true; | 223 return true; |
248 } | 224 } |
249 | 225 |
250 void GpuProcessHost::OnChannelEstablished( | 226 void GpuProcessHost::OnChannelEstablished( |
(...skipping 27 matching lines...) Expand all Loading... |
278 void GpuProcessHost::OnSynchronizeReply() { | 254 void GpuProcessHost::OnSynchronizeReply() { |
279 // Guard against race conditions in abrupt GPU process termination. | 255 // Guard against race conditions in abrupt GPU process termination. |
280 if (queued_synchronization_replies_.size() > 0) { | 256 if (queued_synchronization_replies_.size() > 0) { |
281 const SynchronizationRequest& request = | 257 const SynchronizationRequest& request = |
282 queued_synchronization_replies_.front(); | 258 queued_synchronization_replies_.front(); |
283 SendSynchronizationReply(request.reply, request.filter); | 259 SendSynchronizationReply(request.reply, request.filter); |
284 queued_synchronization_replies_.pop(); | 260 queued_synchronization_replies_.pop(); |
285 } | 261 } |
286 } | 262 } |
287 | 263 |
288 #if defined(OS_LINUX) | |
289 | |
290 namespace { | |
291 | |
292 void SendDelayedReply(IPC::Message* reply_msg) { | |
293 GpuProcessHost::Get()->Send(reply_msg); | |
294 } | |
295 | |
296 void GetViewXIDDispatcher(gfx::NativeViewId id, IPC::Message* reply_msg) { | |
297 XID xid; | |
298 | |
299 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); | |
300 if (!manager->GetPermanentXIDForId(&xid, id)) { | |
301 DLOG(ERROR) << "Can't find XID for view id " << id; | |
302 xid = 0; | |
303 } | |
304 | |
305 GpuHostMsg_GetViewXID::WriteReplyParams(reply_msg, xid); | |
306 | |
307 // Have to reply from IO thread. | |
308 BrowserThread::PostTask( | |
309 BrowserThread::IO, FROM_HERE, | |
310 NewRunnableFunction(&SendDelayedReply, reply_msg)); | |
311 } | |
312 | |
313 void ReleaseXIDDispatcher(unsigned long xid) { | |
314 GtkNativeViewManager* manager = GtkNativeViewManager::GetInstance(); | |
315 manager->ReleasePermanentXID(xid); | |
316 } | |
317 | |
318 void ResizeXIDDispatcher(unsigned long xid, gfx::Size size, | |
319 IPC::Message *reply_msg) { | |
320 GdkWindow* window = reinterpret_cast<GdkWindow*>(gdk_xid_table_lookup(xid)); | |
321 if (window) { | |
322 Display* display = GDK_WINDOW_XDISPLAY(window); | |
323 gdk_window_resize(window, size.width(), size.height()); | |
324 XSync(display, False); | |
325 } | |
326 | |
327 GpuHostMsg_ResizeXID::WriteReplyParams(reply_msg, (window != NULL)); | |
328 | |
329 // Have to reply from IO thread. | |
330 BrowserThread::PostTask( | |
331 BrowserThread::IO, FROM_HERE, | |
332 NewRunnableFunction(&SendDelayedReply, reply_msg)); | |
333 } | |
334 | |
335 } // namespace | |
336 | |
337 void GpuProcessHost::OnGetViewXID(gfx::NativeViewId id, | |
338 IPC::Message *reply_msg) { | |
339 // Have to request a permanent XID from UI thread. | |
340 BrowserThread::PostTask( | |
341 BrowserThread::UI, FROM_HERE, | |
342 NewRunnableFunction(&GetViewXIDDispatcher, id, reply_msg)); | |
343 } | |
344 | |
345 void GpuProcessHost::OnReleaseXID(unsigned long xid) { | |
346 // Have to release a permanent XID from UI thread. | |
347 BrowserThread::PostTask( | |
348 BrowserThread::UI, FROM_HERE, | |
349 NewRunnableFunction(&ReleaseXIDDispatcher, xid)); | |
350 } | |
351 | |
352 void GpuProcessHost::OnResizeXID(unsigned long xid, gfx::Size size, | |
353 IPC::Message *reply_msg) { | |
354 // Have to resize the window from UI thread. | |
355 BrowserThread::PostTask( | |
356 BrowserThread::UI, FROM_HERE, | |
357 NewRunnableFunction(&ResizeXIDDispatcher, xid, size, reply_msg)); | |
358 } | |
359 | |
360 #elif defined(OS_MACOSX) | |
361 | |
362 namespace { | |
363 | |
364 class SetIOSurfaceDispatcher : public Task { | |
365 public: | |
366 SetIOSurfaceDispatcher( | |
367 const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params) | |
368 : params_(params) { | |
369 } | |
370 | |
371 void Run() { | |
372 RenderViewHost* host = RenderViewHost::FromID(params_.renderer_id, | |
373 params_.render_view_id); | |
374 if (!host) | |
375 return; | |
376 RenderWidgetHostView* view = host->view(); | |
377 if (!view) | |
378 return; | |
379 view->AcceleratedSurfaceSetIOSurface(params_.window, | |
380 params_.width, | |
381 params_.height, | |
382 params_.identifier); | |
383 } | |
384 | |
385 private: | |
386 GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params_; | |
387 | |
388 DISALLOW_COPY_AND_ASSIGN(SetIOSurfaceDispatcher); | |
389 }; | |
390 | |
391 } // namespace | |
392 | |
393 void GpuProcessHost::OnAcceleratedSurfaceSetIOSurface( | |
394 const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params) { | |
395 BrowserThread::PostTask( | |
396 BrowserThread::UI, FROM_HERE, | |
397 new SetIOSurfaceDispatcher(params)); | |
398 } | |
399 | |
400 namespace { | |
401 | |
402 class BuffersSwappedDispatcher : public Task { | |
403 public: | |
404 BuffersSwappedDispatcher( | |
405 int renderer_id, | |
406 int render_view_id, | |
407 gfx::PluginWindowHandle window, | |
408 uint64 surface_id, | |
409 int32 route_id, | |
410 uint64 swap_buffers_count) | |
411 : renderer_id_(renderer_id), | |
412 render_view_id_(render_view_id), | |
413 window_(window), | |
414 surface_id_(surface_id), | |
415 route_id_(route_id), | |
416 swap_buffers_count_(swap_buffers_count) { | |
417 } | |
418 | |
419 void Run() { | |
420 RenderViewHost* host = RenderViewHost::FromID(renderer_id_, | |
421 render_view_id_); | |
422 if (!host) | |
423 return; | |
424 RenderWidgetHostView* view = host->view(); | |
425 if (!view) | |
426 return; | |
427 view->AcceleratedSurfaceBuffersSwapped( | |
428 // Parameters needed to swap the IOSurface. | |
429 window_, | |
430 surface_id_, | |
431 // Parameters needed to formulate an acknowledgment. | |
432 renderer_id_, | |
433 route_id_, | |
434 swap_buffers_count_); | |
435 } | |
436 | |
437 private: | |
438 int renderer_id_; | |
439 int render_view_id_; | |
440 gfx::PluginWindowHandle window_; | |
441 uint64 surface_id_; | |
442 int32 route_id_; | |
443 uint64 swap_buffers_count_; | |
444 | |
445 DISALLOW_COPY_AND_ASSIGN(BuffersSwappedDispatcher); | |
446 }; | |
447 | |
448 } // namespace | |
449 | |
450 void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped( | |
451 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) { | |
452 BrowserThread::PostTask( | |
453 BrowserThread::UI, FROM_HERE, | |
454 new BuffersSwappedDispatcher( | |
455 // These are the parameters needed to look up the IOSurface | |
456 // on this side. | |
457 params.renderer_id, | |
458 params.render_view_id, | |
459 params.window, | |
460 params.surface_id, | |
461 // These are additional parameters needed to formulate an | |
462 // acknowledgment. | |
463 params.route_id, | |
464 params.swap_buffers_count)); | |
465 } | |
466 | |
467 #elif defined(OS_WIN) | |
468 | |
469 namespace { | |
470 | |
471 void SendDelayedReply(IPC::Message* reply_msg) { | |
472 GpuProcessHost::Get()->Send(reply_msg); | |
473 } | |
474 | |
475 void GetCompositorHostWindowDispatcher( | |
476 int renderer_id, | |
477 int render_view_id, | |
478 IPC::Message* reply_msg) { | |
479 RenderViewHost* host = RenderViewHost::FromID(renderer_id, | |
480 render_view_id); | |
481 if (!host) { | |
482 GpuHostMsg_GetCompositorHostWindow::WriteReplyParams(reply_msg, | |
483 gfx::kNullPluginWindow); | |
484 BrowserThread::PostTask( | |
485 BrowserThread::IO, FROM_HERE, | |
486 NewRunnableFunction(&SendDelayedReply, reply_msg)); | |
487 return; | |
488 } | |
489 | |
490 RenderWidgetHostView* view = host->view(); | |
491 gfx::PluginWindowHandle id = view->GetCompositorHostWindow(); | |
492 | |
493 | |
494 GpuHostMsg_GetCompositorHostWindow::WriteReplyParams(reply_msg, id); | |
495 BrowserThread::PostTask( | |
496 BrowserThread::IO, FROM_HERE, | |
497 NewRunnableFunction(&SendDelayedReply, reply_msg)); | |
498 } | |
499 | |
500 } // namespace | |
501 | |
502 void GpuProcessHost::OnGetCompositorHostWindow( | |
503 int renderer_id, | |
504 int render_view_id, | |
505 IPC::Message* reply_message) { | |
506 BrowserThread::PostTask( | |
507 BrowserThread::UI, FROM_HERE, | |
508 NewRunnableFunction(&GetCompositorHostWindowDispatcher, | |
509 renderer_id, render_view_id, reply_message)); | |
510 } | |
511 | |
512 #endif | |
513 | |
514 void GpuProcessHost::SendEstablishChannelReply( | 264 void GpuProcessHost::SendEstablishChannelReply( |
515 const IPC::ChannelHandle& channel, | 265 const IPC::ChannelHandle& channel, |
516 const GPUInfo& gpu_info, | 266 const GPUInfo& gpu_info, |
517 RenderMessageFilter* filter) { | 267 RenderMessageFilter* filter) { |
518 ViewMsg_GpuChannelEstablished* message = | 268 ViewMsg_GpuChannelEstablished* message = |
519 new ViewMsg_GpuChannelEstablished(channel, gpu_info); | 269 new ViewMsg_GpuChannelEstablished(channel, gpu_info); |
520 // If the renderer process is performing synchronous initialization, | 270 // If the renderer process is performing synchronous initialization, |
521 // it needs to handle this message before receiving the reply for | 271 // it needs to handle this message before receiving the reply for |
522 // the synchronous ViewHostMsg_SynchronizeGpu message. | 272 // the synchronous ViewHostMsg_SynchronizeGpu message. |
523 message->set_unblock(true); | 273 message->set_unblock(true); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); | 400 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); |
651 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || | 401 if (browser_command_line.HasSwitch(switches::kIgnoreGpuBlacklist) || |
652 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { | 402 blacklist->LoadGpuBlacklist(gpu_blacklist_json.as_string(), true)) { |
653 gpu_blacklist_.reset(blacklist); | 403 gpu_blacklist_.reset(blacklist); |
654 return true; | 404 return true; |
655 } | 405 } |
656 delete blacklist; | 406 delete blacklist; |
657 return false; | 407 return false; |
658 } | 408 } |
659 | 409 |
OLD | NEW |