| 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 |