| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 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 "content/renderer/browser_plugin/browser_plugin.h" | 5 #include "content/renderer/browser_plugin/browser_plugin.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/json/json_string_value_serializer.h" | 8 #include "base/json/json_string_value_serializer.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "content/common/browser_plugin/browser_plugin_constants.h" | 13 #include "content/common/browser_plugin/browser_plugin_constants.h" |
| 14 #include "content/common/browser_plugin/browser_plugin_messages.h" | 14 #include "content/common/browser_plugin/browser_plugin_messages.h" |
| 15 #include "content/common/view_messages.h" | 15 #include "content/common/view_messages.h" |
| 16 #include "content/public/common/content_client.h" | 16 #include "content/public/common/content_client.h" |
| 17 #include "content/public/common/content_switches.h" | 17 #include "content/public/common/content_switches.h" |
| 18 #include "content/public/renderer/content_renderer_client.h" | 18 #include "content/public/renderer/content_renderer_client.h" |
| 19 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" | 19 #include "content/renderer/browser_plugin/browser_plugin_bindings.h" |
| 20 #include "content/renderer/browser_plugin/browser_plugin_manager.h" | 20 #include "content/renderer/browser_plugin/browser_plugin_manager.h" |
| 21 #include "content/renderer/child_frame_compositing_helper.h" | 21 #include "content/renderer/child_frame_compositing_helper.h" |
| 22 #include "content/renderer/cursor_utils.h" | 22 #include "content/renderer/cursor_utils.h" |
| 23 #include "content/renderer/drop_data_builder.h" | 23 #include "content/renderer/drop_data_builder.h" |
| 24 #include "content/renderer/render_process_impl.h" | |
| 25 #include "content/renderer/render_thread_impl.h" | 24 #include "content/renderer/render_thread_impl.h" |
| 26 #include "content/renderer/sad_plugin.h" | 25 #include "content/renderer/sad_plugin.h" |
| 27 #include "content/renderer/v8_value_converter_impl.h" | 26 #include "content/renderer/v8_value_converter_impl.h" |
| 28 #include "skia/ext/platform_canvas.h" | |
| 29 #include "third_party/WebKit/public/platform/WebRect.h" | 27 #include "third_party/WebKit/public/platform/WebRect.h" |
| 30 #include "third_party/WebKit/public/web/WebBindings.h" | 28 #include "third_party/WebKit/public/web/WebBindings.h" |
| 31 #include "third_party/WebKit/public/web/WebDOMCustomEvent.h" | 29 #include "third_party/WebKit/public/web/WebDOMCustomEvent.h" |
| 32 #include "third_party/WebKit/public/web/WebDocument.h" | 30 #include "third_party/WebKit/public/web/WebDocument.h" |
| 33 #include "third_party/WebKit/public/web/WebElement.h" | 31 #include "third_party/WebKit/public/web/WebElement.h" |
| 34 #include "third_party/WebKit/public/web/WebInputEvent.h" | 32 #include "third_party/WebKit/public/web/WebInputEvent.h" |
| 35 #include "third_party/WebKit/public/web/WebLocalFrame.h" | 33 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 36 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 34 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
| 37 #include "third_party/WebKit/public/web/WebPluginParams.h" | 35 #include "third_party/WebKit/public/web/WebPluginParams.h" |
| 38 #include "third_party/WebKit/public/web/WebScriptSource.h" | 36 #include "third_party/WebKit/public/web/WebScriptSource.h" |
| 39 #include "third_party/WebKit/public/web/WebView.h" | 37 #include "third_party/WebKit/public/web/WebView.h" |
| 38 #include "third_party/skia/include/core/SkCanvas.h" |
| 40 #include "ui/events/keycodes/keyboard_codes.h" | 39 #include "ui/events/keycodes/keyboard_codes.h" |
| 41 | 40 |
| 42 #if defined (OS_WIN) | 41 #if defined (OS_WIN) |
| 43 #include "base/sys_info.h" | 42 #include "base/sys_info.h" |
| 44 #endif | 43 #endif |
| 45 | 44 |
| 46 using blink::WebCanvas; | 45 using blink::WebCanvas; |
| 47 using blink::WebPluginContainer; | 46 using blink::WebPluginContainer; |
| 48 using blink::WebPluginParams; | 47 using blink::WebPluginParams; |
| 49 using blink::WebPoint; | 48 using blink::WebPoint; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 64 } // namespace | 63 } // namespace |
| 65 | 64 |
| 66 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view, | 65 BrowserPlugin::BrowserPlugin(RenderViewImpl* render_view, |
| 67 blink::WebFrame* frame, | 66 blink::WebFrame* frame, |
| 68 bool auto_navigate) | 67 bool auto_navigate) |
| 69 : guest_instance_id_(browser_plugin::kInstanceIDNone), | 68 : guest_instance_id_(browser_plugin::kInstanceIDNone), |
| 70 attached_(false), | 69 attached_(false), |
| 71 render_view_(render_view->AsWeakPtr()), | 70 render_view_(render_view->AsWeakPtr()), |
| 72 render_view_routing_id_(render_view->GetRoutingID()), | 71 render_view_routing_id_(render_view->GetRoutingID()), |
| 73 container_(NULL), | 72 container_(NULL), |
| 74 damage_buffer_sequence_id_(0), | |
| 75 paint_ack_received_(true), | 73 paint_ack_received_(true), |
| 76 last_device_scale_factor_(1.0f), | 74 last_device_scale_factor_(1.0f), |
| 77 sad_guest_(NULL), | 75 sad_guest_(NULL), |
| 78 guest_crashed_(false), | 76 guest_crashed_(false), |
| 79 is_auto_size_state_dirty_(false), | 77 is_auto_size_state_dirty_(false), |
| 80 persist_storage_(false), | 78 persist_storage_(false), |
| 81 valid_partition_id_(true), | 79 valid_partition_id_(true), |
| 82 content_window_routing_id_(MSG_ROUTING_NONE), | 80 content_window_routing_id_(MSG_ROUTING_NONE), |
| 83 plugin_focused_(false), | 81 plugin_focused_(false), |
| 84 visible_(true), | 82 visible_(true), |
| 85 auto_navigate_(auto_navigate), | 83 auto_navigate_(auto_navigate), |
| 86 before_first_navigation_(true), | 84 before_first_navigation_(true), |
| 87 mouse_locked_(false), | 85 mouse_locked_(false), |
| 88 browser_plugin_manager_(render_view->GetBrowserPluginManager()), | 86 browser_plugin_manager_(render_view->GetBrowserPluginManager()), |
| 89 compositing_enabled_(false), | |
| 90 embedder_frame_url_(frame->document().url()), | 87 embedder_frame_url_(frame->document().url()), |
| 91 weak_ptr_factory_(this) { | 88 weak_ptr_factory_(this) { |
| 92 } | 89 } |
| 93 | 90 |
| 94 BrowserPlugin::~BrowserPlugin() { | 91 BrowserPlugin::~BrowserPlugin() { |
| 95 // If the BrowserPlugin has never navigated then the browser process and | 92 // If the BrowserPlugin has never navigated then the browser process and |
| 96 // BrowserPluginManager don't know about it and so there is nothing to do | 93 // BrowserPluginManager don't know about it and so there is nothing to do |
| 97 // here. | 94 // here. |
| 98 if (!HasGuestInstanceID()) | 95 if (!HasGuestInstanceID()) |
| 99 return; | 96 return; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 321 |
| 325 max_auto_size_ = params->max_size; | 322 max_auto_size_ = params->max_size; |
| 326 } else { | 323 } else { |
| 327 max_auto_size_ = gfx::Size(); | 324 max_auto_size_ = gfx::Size(); |
| 328 } | 325 } |
| 329 } | 326 } |
| 330 | 327 |
| 331 void BrowserPlugin::UpdateGuestAutoSizeState(bool auto_size_enabled) { | 328 void BrowserPlugin::UpdateGuestAutoSizeState(bool auto_size_enabled) { |
| 332 // If we haven't yet heard back from the guest about the last resize request, | 329 // If we haven't yet heard back from the guest about the last resize request, |
| 333 // then we don't issue another request until we do in | 330 // then we don't issue another request until we do in |
| 334 // BrowserPlugin::UpdateRect. | 331 // BrowserPlugin::OnUpdateRect. |
| 335 if (!HasGuestInstanceID() || !paint_ack_received_) | 332 if (!HasGuestInstanceID() || !paint_ack_received_) |
| 336 return; | 333 return; |
| 337 | 334 |
| 338 BrowserPluginHostMsg_AutoSize_Params auto_size_params; | 335 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| 339 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; | 336 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
| 340 if (auto_size_enabled) { | 337 if (auto_size_enabled) { |
| 341 GetDamageBufferWithSizeParams(&auto_size_params, | 338 GetSizeParams(&auto_size_params, &resize_guest_params, true); |
| 342 &resize_guest_params, | |
| 343 true); | |
| 344 } else { | 339 } else { |
| 345 GetDamageBufferWithSizeParams(NULL, &resize_guest_params, true); | 340 GetSizeParams(NULL, &resize_guest_params, true); |
| 346 } | 341 } |
| 347 paint_ack_received_ = false; | 342 paint_ack_received_ = false; |
| 348 browser_plugin_manager()->Send( | 343 browser_plugin_manager()->Send( |
| 349 new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_, | 344 new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_, |
| 350 guest_instance_id_, | 345 guest_instance_id_, |
| 351 auto_size_params, | 346 auto_size_params, |
| 352 resize_guest_params)); | 347 resize_guest_params)); |
| 353 } | 348 } |
| 354 | 349 |
| 355 // static | |
| 356 bool BrowserPlugin::UsesDamageBuffer( | |
| 357 const BrowserPluginMsg_UpdateRect_Params& params) { | |
| 358 return params.damage_buffer_sequence_id != 0 || params.needs_ack; | |
| 359 } | |
| 360 | |
| 361 bool BrowserPlugin::UsesPendingDamageBuffer( | |
| 362 const BrowserPluginMsg_UpdateRect_Params& params) { | |
| 363 if (!pending_damage_buffer_) | |
| 364 return false; | |
| 365 return damage_buffer_sequence_id_ == params.damage_buffer_sequence_id; | |
| 366 } | |
| 367 | |
| 368 void BrowserPlugin::OnInstanceIDAllocated(int guest_instance_id) { | 350 void BrowserPlugin::OnInstanceIDAllocated(int guest_instance_id) { |
| 369 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); | 351 CHECK(guest_instance_id != browser_plugin::kInstanceIDNone); |
| 370 | 352 |
| 371 if (auto_navigate_) { | 353 if (auto_navigate_) { |
| 372 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); | 354 scoped_ptr<base::DictionaryValue> params(new base::DictionaryValue()); |
| 373 Attach(guest_instance_id, params.Pass()); | 355 Attach(guest_instance_id, params.Pass()); |
| 374 return; | 356 return; |
| 375 } | 357 } |
| 376 | 358 |
| 377 std::map<std::string, base::Value*> props; | 359 std::map<std::string, base::Value*> props; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 396 | 378 |
| 397 BrowserPluginHostMsg_Attach_Params attach_params; | 379 BrowserPluginHostMsg_Attach_Params attach_params; |
| 398 attach_params.focused = ShouldGuestBeFocused(); | 380 attach_params.focused = ShouldGuestBeFocused(); |
| 399 attach_params.visible = visible_; | 381 attach_params.visible = visible_; |
| 400 attach_params.opaque = !GetAllowTransparencyAttribute(); | 382 attach_params.opaque = !GetAllowTransparencyAttribute(); |
| 401 attach_params.name = GetNameAttribute(); | 383 attach_params.name = GetNameAttribute(); |
| 402 attach_params.storage_partition_id = storage_partition_id_; | 384 attach_params.storage_partition_id = storage_partition_id_; |
| 403 attach_params.persist_storage = persist_storage_; | 385 attach_params.persist_storage = persist_storage_; |
| 404 attach_params.src = GetSrcAttribute(); | 386 attach_params.src = GetSrcAttribute(); |
| 405 attach_params.embedder_frame_url = embedder_frame_url_; | 387 attach_params.embedder_frame_url = embedder_frame_url_; |
| 406 GetDamageBufferWithSizeParams(&attach_params.auto_size_params, | 388 GetSizeParams(&attach_params.auto_size_params, |
| 407 &attach_params.resize_guest_params, | 389 &attach_params.resize_guest_params, |
| 408 false); | 390 false); |
| 409 | 391 |
| 410 browser_plugin_manager()->Send( | 392 browser_plugin_manager()->Send( |
| 411 new BrowserPluginHostMsg_Attach(render_view_routing_id_, | 393 new BrowserPluginHostMsg_Attach(render_view_routing_id_, |
| 412 guest_instance_id_, attach_params, | 394 guest_instance_id_, attach_params, |
| 413 *extra_params)); | 395 *extra_params)); |
| 414 } | 396 } |
| 415 | 397 |
| 416 void BrowserPlugin::DidCommitCompositorFrame() { | 398 void BrowserPlugin::DidCommitCompositorFrame() { |
| 417 if (compositing_helper_.get()) | 399 if (compositing_helper_.get()) |
| 418 compositing_helper_->DidCommitCompositorFrame(); | 400 compositing_helper_->DidCommitCompositorFrame(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 param.b.producing_route_id, | 444 param.b.producing_route_id, |
| 463 param.b.output_surface_id, | 445 param.b.output_surface_id, |
| 464 param.b.producing_host_id, | 446 param.b.producing_host_id, |
| 465 param.b.shared_memory_handle); | 447 param.b.shared_memory_handle); |
| 466 } | 448 } |
| 467 | 449 |
| 468 void BrowserPlugin::OnCopyFromCompositingSurface(int guest_instance_id, | 450 void BrowserPlugin::OnCopyFromCompositingSurface(int guest_instance_id, |
| 469 int request_id, | 451 int request_id, |
| 470 gfx::Rect source_rect, | 452 gfx::Rect source_rect, |
| 471 gfx::Size dest_size) { | 453 gfx::Size dest_size) { |
| 472 if (!compositing_enabled_) { | 454 if (!compositing_helper_) { |
| 473 browser_plugin_manager()->Send( | 455 browser_plugin_manager()->Send( |
| 474 new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck( | 456 new BrowserPluginHostMsg_CopyFromCompositingSurfaceAck( |
| 475 render_view_routing_id_, | 457 render_view_routing_id_, |
| 476 guest_instance_id_, | 458 guest_instance_id_, |
| 477 request_id, | 459 request_id, |
| 478 SkBitmap())); | 460 SkBitmap())); |
| 479 return; | 461 return; |
| 480 } | 462 } |
| 481 compositing_helper_->CopyFromCompositingSurface(request_id, source_rect, | 463 compositing_helper_->CopyFromCompositingSurface(request_id, source_rect, |
| 482 dest_size); | 464 dest_size); |
| 483 } | 465 } |
| 484 | 466 |
| 485 void BrowserPlugin::OnGuestContentWindowReady(int guest_instance_id, | 467 void BrowserPlugin::OnGuestContentWindowReady(int guest_instance_id, |
| 486 int content_window_routing_id) { | 468 int content_window_routing_id) { |
| 487 DCHECK(content_window_routing_id != MSG_ROUTING_NONE); | 469 DCHECK(content_window_routing_id != MSG_ROUTING_NONE); |
| 488 content_window_routing_id_ = content_window_routing_id; | 470 content_window_routing_id_ = content_window_routing_id; |
| 489 } | 471 } |
| 490 | 472 |
| 491 void BrowserPlugin::OnGuestGone(int guest_instance_id) { | 473 void BrowserPlugin::OnGuestGone(int guest_instance_id) { |
| 492 guest_crashed_ = true; | 474 guest_crashed_ = true; |
| 493 | 475 |
| 494 // Turn off compositing so we can display the sad graphic. Changes to | 476 // Turn off compositing so we can display the sad graphic. Changes to |
| 495 // compositing state will show up at a later time after a layout and commit. | 477 // compositing state will show up at a later time after a layout and commit. |
| 496 EnableCompositing(false); | 478 EnableCompositing(false); |
| 497 if (compositing_helper_) { | |
| 498 compositing_helper_->OnContainerDestroy(); | |
| 499 compositing_helper_ = NULL; | |
| 500 } | |
| 501 | 479 |
| 502 // Queue up showing the sad graphic to give content embedders an opportunity | 480 // Queue up showing the sad graphic to give content embedders an opportunity |
| 503 // to fire their listeners and potentially overlay the webview with custom | 481 // to fire their listeners and potentially overlay the webview with custom |
| 504 // behavior. If the BrowserPlugin is destroyed in the meantime, then the | 482 // behavior. If the BrowserPlugin is destroyed in the meantime, then the |
| 505 // task will not be executed. | 483 // task will not be executed. |
| 506 base::MessageLoop::current()->PostTask( | 484 base::MessageLoop::current()->PostTask( |
| 507 FROM_HERE, | 485 FROM_HERE, |
| 508 base::Bind(&BrowserPlugin::ShowSadGraphic, | 486 base::Bind(&BrowserPlugin::ShowSadGraphic, |
| 509 weak_ptr_factory_.GetWeakPtr())); | 487 weak_ptr_factory_.GetWeakPtr())); |
| 510 } | 488 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 539 } | 517 } |
| 540 | 518 |
| 541 void BrowserPlugin::OnUpdatedName(int guest_instance_id, | 519 void BrowserPlugin::OnUpdatedName(int guest_instance_id, |
| 542 const std::string& name) { | 520 const std::string& name) { |
| 543 UpdateDOMAttribute(browser_plugin::kAttributeName, name); | 521 UpdateDOMAttribute(browser_plugin::kAttributeName, name); |
| 544 } | 522 } |
| 545 | 523 |
| 546 void BrowserPlugin::OnUpdateRect( | 524 void BrowserPlugin::OnUpdateRect( |
| 547 int guest_instance_id, | 525 int guest_instance_id, |
| 548 const BrowserPluginMsg_UpdateRect_Params& params) { | 526 const BrowserPluginMsg_UpdateRect_Params& params) { |
| 527 // Note that there is no need to send ACK for this message. |
| 549 // If the guest has updated pixels then it is no longer crashed. | 528 // If the guest has updated pixels then it is no longer crashed. |
| 550 guest_crashed_ = false; | 529 guest_crashed_ = false; |
| 551 | 530 |
| 552 bool use_new_damage_buffer = !backing_store_; | |
| 553 BrowserPluginHostMsg_AutoSize_Params auto_size_params; | |
| 554 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; | |
| 555 // If we have a pending damage buffer, and the guest has begun to use the | |
| 556 // damage buffer then we know the guest will no longer use the current | |
| 557 // damage buffer. At this point, we drop the current damage buffer, and | |
| 558 // mark the pending damage buffer as the current damage buffer. | |
| 559 if (UsesPendingDamageBuffer(params)) { | |
| 560 SwapDamageBuffers(); | |
| 561 use_new_damage_buffer = true; | |
| 562 } | |
| 563 | |
| 564 bool auto_size = GetAutoSizeAttribute(); | 531 bool auto_size = GetAutoSizeAttribute(); |
| 565 // We receive a resize ACK in regular mode, but not in autosize. | 532 // We receive a resize ACK in regular mode, but not in autosize. |
| 566 // In SW, |paint_ack_received_| is reset in SwapDamageBuffers(). | 533 // In Compositing mode, we need to do it here so we can continue sending |
| 567 // In HW mode, we need to do it here so we can continue sending | |
| 568 // resize messages when needed. | 534 // resize messages when needed. |
| 569 if (params.is_resize_ack || | 535 if (params.is_resize_ack || (auto_size || is_auto_size_state_dirty_)) |
| 570 (!params.needs_ack && (auto_size || is_auto_size_state_dirty_))) { | |
| 571 paint_ack_received_ = true; | 536 paint_ack_received_ = true; |
| 572 } | |
| 573 | 537 |
| 574 bool was_auto_size_state_dirty = auto_size && is_auto_size_state_dirty_; | 538 bool was_auto_size_state_dirty = auto_size && is_auto_size_state_dirty_; |
| 575 is_auto_size_state_dirty_ = false; | 539 is_auto_size_state_dirty_ = false; |
| 576 | 540 |
| 577 if ((!auto_size && (width() != params.view_size.width() || | 541 if ((!auto_size && (width() != params.view_size.width() || |
| 578 height() != params.view_size.height())) || | 542 height() != params.view_size.height())) || |
| 579 (auto_size && was_auto_size_state_dirty) || | 543 (auto_size && was_auto_size_state_dirty) || |
| 580 GetDeviceScaleFactor() != params.scale_factor) { | 544 GetDeviceScaleFactor() != params.scale_factor) { |
| 581 // We are HW accelerated, render widget does not expect an ack, | 545 UpdateGuestAutoSizeState(auto_size); |
| 582 // but we still need to update the size. | |
| 583 if (!params.needs_ack) { | |
| 584 UpdateGuestAutoSizeState(auto_size); | |
| 585 return; | |
| 586 } | |
| 587 | |
| 588 if (!paint_ack_received_) { | |
| 589 // The guest has not yet responded to the last resize request, and | |
| 590 // so we don't want to do anything at this point other than ACK the guest. | |
| 591 if (auto_size) | |
| 592 PopulateAutoSizeParameters(&auto_size_params, auto_size); | |
| 593 } else { | |
| 594 // If we have no pending damage buffer, then the guest has not caught up | |
| 595 // with the BrowserPlugin container. We now tell the guest about the new | |
| 596 // container size. | |
| 597 if (auto_size) { | |
| 598 GetDamageBufferWithSizeParams(&auto_size_params, | |
| 599 &resize_guest_params, | |
| 600 was_auto_size_state_dirty); | |
| 601 } else { | |
| 602 GetDamageBufferWithSizeParams(NULL, | |
| 603 &resize_guest_params, | |
| 604 was_auto_size_state_dirty); | |
| 605 } | |
| 606 } | |
| 607 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( | |
| 608 render_view_routing_id_, | |
| 609 guest_instance_id_, | |
| 610 auto_size_params, | |
| 611 resize_guest_params)); | |
| 612 return; | 546 return; |
| 613 } | 547 } |
| 614 | 548 |
| 615 if (auto_size && (params.view_size != last_view_size_)) { | 549 if (auto_size && (params.view_size != last_view_size_)) |
| 616 if (backing_store_) | |
| 617 backing_store_->Clear(SK_ColorWHITE); | |
| 618 last_view_size_ = params.view_size; | 550 last_view_size_ = params.view_size; |
| 619 } | |
| 620 | 551 |
| 621 if (UsesDamageBuffer(params)) { | 552 BrowserPluginHostMsg_AutoSize_Params auto_size_params; |
| 622 | 553 BrowserPluginHostMsg_ResizeGuest_Params resize_guest_params; |
| 623 // If we are seeing damage buffers, HW compositing should be turned off. | |
| 624 EnableCompositing(false); | |
| 625 | |
| 626 // If we are now using a new damage buffer, then that means that the guest | |
| 627 // has updated its size state in response to a resize request. We change | |
| 628 // the backing store's size to accomodate the new damage buffer size. | |
| 629 if (use_new_damage_buffer) { | |
| 630 int backing_store_width = auto_size ? GetAdjustedMaxWidth() : width(); | |
| 631 int backing_store_height = auto_size ? GetAdjustedMaxHeight(): height(); | |
| 632 backing_store_.reset( | |
| 633 new BrowserPluginBackingStore( | |
| 634 gfx::Size(backing_store_width, backing_store_height), | |
| 635 params.scale_factor)); | |
| 636 } | |
| 637 | |
| 638 // If we just transitioned from the compositing path to the software path | |
| 639 // then we might not yet have a damage buffer. | |
| 640 if (current_damage_buffer_) { | |
| 641 // Update the backing store. | |
| 642 if (!params.scroll_rect.IsEmpty()) { | |
| 643 backing_store_->ScrollBackingStore(params.scroll_delta, | |
| 644 params.scroll_rect, | |
| 645 params.view_size); | |
| 646 } | |
| 647 backing_store_->PaintToBackingStore(params.bitmap_rect, | |
| 648 params.copy_rects, | |
| 649 current_damage_buffer_->memory()); | |
| 650 // Invalidate the container. | |
| 651 // If the BrowserPlugin is scheduled to be deleted, then container_ will | |
| 652 // be NULL so we shouldn't attempt to access it. | |
| 653 if (container_) | |
| 654 container_->invalidate(); | |
| 655 } | |
| 656 } | |
| 657 | 554 |
| 658 // BrowserPluginHostMsg_UpdateRect_ACK is used by both the compositing and | 555 // BrowserPluginHostMsg_UpdateRect_ACK is used by both the compositing and |
| 659 // software paths to piggyback updated autosize parameters. | 556 // software paths to piggyback updated autosize parameters. |
| 660 if (auto_size) | 557 if (auto_size) |
| 661 PopulateAutoSizeParameters(&auto_size_params, auto_size); | 558 PopulateAutoSizeParameters(&auto_size_params, auto_size); |
| 662 browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateRect_ACK( | 559 |
| 663 render_view_routing_id_, | 560 browser_plugin_manager()->Send( |
| 664 guest_instance_id_, | 561 new BrowserPluginHostMsg_SetAutoSize(render_view_routing_id_, |
| 665 auto_size_params, | 562 guest_instance_id_, |
| 666 resize_guest_params)); | 563 auto_size_params, |
| 564 resize_guest_params)); |
| 667 } | 565 } |
| 668 | 566 |
| 669 void BrowserPlugin::ParseSizeContraintsChanged() { | 567 void BrowserPlugin::ParseSizeContraintsChanged() { |
| 670 bool auto_size = GetAutoSizeAttribute(); | 568 bool auto_size = GetAutoSizeAttribute(); |
| 671 if (auto_size) { | 569 if (auto_size) { |
| 672 is_auto_size_state_dirty_ = true; | 570 is_auto_size_state_dirty_ = true; |
| 673 UpdateGuestAutoSizeState(true); | 571 UpdateGuestAutoSizeState(true); |
| 674 } | 572 } |
| 675 } | 573 } |
| 676 | 574 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 return true; | 632 return true; |
| 735 } | 633 } |
| 736 | 634 |
| 737 bool BrowserPlugin::CanRemovePartitionAttribute(std::string* error_message) { | 635 bool BrowserPlugin::CanRemovePartitionAttribute(std::string* error_message) { |
| 738 if (HasGuestInstanceID()) | 636 if (HasGuestInstanceID()) |
| 739 *error_message = browser_plugin::kErrorCannotRemovePartition; | 637 *error_message = browser_plugin::kErrorCannotRemovePartition; |
| 740 return !HasGuestInstanceID(); | 638 return !HasGuestInstanceID(); |
| 741 } | 639 } |
| 742 | 640 |
| 743 void BrowserPlugin::ShowSadGraphic() { | 641 void BrowserPlugin::ShowSadGraphic() { |
| 744 // We won't paint the contents of the current backing store again so we might | |
| 745 // as well toss it out and save memory. | |
| 746 backing_store_.reset(); | |
| 747 // If the BrowserPlugin is scheduled to be deleted, then container_ will be | 642 // If the BrowserPlugin is scheduled to be deleted, then container_ will be |
| 748 // NULL so we shouldn't attempt to access it. | 643 // NULL so we shouldn't attempt to access it. |
| 749 if (container_) | 644 if (container_) |
| 750 container_->invalidate(); | 645 container_->invalidate(); |
| 751 } | 646 } |
| 752 | 647 |
| 753 void BrowserPlugin::ParseAttributes() { | 648 void BrowserPlugin::ParseAttributes() { |
| 754 // TODO(mthiesse): Handle errors here? | 649 // TODO(mthiesse): Handle errors here? |
| 755 std::string error; | 650 std::string error; |
| 756 ParsePartitionAttribute(&error); | 651 ParsePartitionAttribute(&error); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 container->allowScriptObjects(); | 752 container->allowScriptObjects(); |
| 858 | 753 |
| 859 bindings_.reset(new BrowserPluginBindings(this)); | 754 bindings_.reset(new BrowserPluginBindings(this)); |
| 860 container_ = container; | 755 container_ = container; |
| 861 container_->setWantsWheelEvents(true); | 756 container_->setWantsWheelEvents(true); |
| 862 ParseAttributes(); | 757 ParseAttributes(); |
| 863 return true; | 758 return true; |
| 864 } | 759 } |
| 865 | 760 |
| 866 void BrowserPlugin::EnableCompositing(bool enable) { | 761 void BrowserPlugin::EnableCompositing(bool enable) { |
| 867 if (compositing_enabled_ == enable) | 762 bool enabled = !!compositing_helper_; |
| 763 if (enabled == enable) |
| 868 return; | 764 return; |
| 869 | 765 |
| 870 compositing_enabled_ = enable; | |
| 871 if (enable) { | 766 if (enable) { |
| 872 // No need to keep the backing store and damage buffer around if we're now | 767 DCHECK(!compositing_helper_.get()); |
| 873 // compositing. | |
| 874 backing_store_.reset(); | |
| 875 current_damage_buffer_.reset(); | |
| 876 if (!compositing_helper_.get()) { | 768 if (!compositing_helper_.get()) { |
| 877 compositing_helper_ = | 769 compositing_helper_ = |
| 878 ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( | 770 ChildFrameCompositingHelper::CreateCompositingHelperForBrowserPlugin( |
| 879 weak_ptr_factory_.GetWeakPtr()); | 771 weak_ptr_factory_.GetWeakPtr()); |
| 880 } | 772 } |
| 881 } else { | |
| 882 if (paint_ack_received_) { | |
| 883 // We're switching back to the software path. We create a new damage | |
| 884 // buffer that can accommodate the current size of the container. | |
| 885 BrowserPluginHostMsg_ResizeGuest_Params params; | |
| 886 // Request a full repaint from the guest even if its size is not actually | |
| 887 // changing. | |
| 888 PopulateResizeGuestParameters(¶ms, | |
| 889 plugin_rect(), | |
| 890 true /* needs_repaint */); | |
| 891 paint_ack_received_ = false; | |
| 892 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( | |
| 893 render_view_routing_id_, | |
| 894 guest_instance_id_, | |
| 895 params)); | |
| 896 } | |
| 897 } | 773 } |
| 898 compositing_helper_->EnableCompositing(enable); | 774 compositing_helper_->EnableCompositing(enable); |
| 899 compositing_helper_->SetContentsOpaque(!GetAllowTransparencyAttribute()); | 775 compositing_helper_->SetContentsOpaque(!GetAllowTransparencyAttribute()); |
| 776 |
| 777 if (!enable) { |
| 778 DCHECK(compositing_helper_.get()); |
| 779 compositing_helper_->OnContainerDestroy(); |
| 780 compositing_helper_ = NULL; |
| 781 } |
| 900 } | 782 } |
| 901 | 783 |
| 902 void BrowserPlugin::destroy() { | 784 void BrowserPlugin::destroy() { |
| 903 // If the plugin was initialized then it has a valid |npp_| identifier, and | 785 // If the plugin was initialized then it has a valid |npp_| identifier, and |
| 904 // the |container_| must clear references to the plugin's script objects. | 786 // the |container_| must clear references to the plugin's script objects. |
| 905 DCHECK(!npp_ || container_); | 787 DCHECK(!npp_ || container_); |
| 906 if (container_) | 788 if (container_) |
| 907 container_->clearScriptObjects(); | 789 container_->clearScriptObjects(); |
| 908 | 790 |
| 909 if (compositing_helper_.get()) | 791 if (compositing_helper_.get()) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 SkIntToScalar(0), | 846 SkIntToScalar(0), |
| 965 SkIntToScalar(plugin_rect_.width()), | 847 SkIntToScalar(plugin_rect_.width()), |
| 966 SkIntToScalar(plugin_rect_.height())); | 848 SkIntToScalar(plugin_rect_.height())); |
| 967 canvas->clipRect(image_data_rect); | 849 canvas->clipRect(image_data_rect); |
| 968 // Paint black or white in case we have nothing in our backing store or we | 850 // Paint black or white in case we have nothing in our backing store or we |
| 969 // need to show a gutter. | 851 // need to show a gutter. |
| 970 SkPaint paint; | 852 SkPaint paint; |
| 971 paint.setStyle(SkPaint::kFill_Style); | 853 paint.setStyle(SkPaint::kFill_Style); |
| 972 paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE); | 854 paint.setColor(guest_crashed_ ? SK_ColorBLACK : SK_ColorWHITE); |
| 973 canvas->drawRect(image_data_rect, paint); | 855 canvas->drawRect(image_data_rect, paint); |
| 974 // Stay a solid color if we have never set a non-empty src, or we don't have a | |
| 975 // backing store. | |
| 976 if (!backing_store_.get() || !HasGuestInstanceID()) | |
| 977 return; | |
| 978 float inverse_scale_factor = 1.0f / backing_store_->GetScaleFactor(); | |
| 979 canvas->scale(inverse_scale_factor, inverse_scale_factor); | |
| 980 canvas->drawBitmap(backing_store_->GetBitmap(), 0, 0); | |
| 981 } | 856 } |
| 982 | 857 |
| 983 // static | 858 // static |
| 984 bool BrowserPlugin::ShouldForwardToBrowserPlugin( | 859 bool BrowserPlugin::ShouldForwardToBrowserPlugin( |
| 985 const IPC::Message& message) { | 860 const IPC::Message& message) { |
| 986 switch (message.type()) { | 861 switch (message.type()) { |
| 987 case BrowserPluginMsg_AdvanceFocus::ID: | 862 case BrowserPluginMsg_AdvanceFocus::ID: |
| 988 case BrowserPluginMsg_Attach_ACK::ID: | 863 case BrowserPluginMsg_Attach_ACK::ID: |
| 989 case BrowserPluginMsg_BuffersSwapped::ID: | 864 case BrowserPluginMsg_BuffersSwapped::ID: |
| 990 case BrowserPluginMsg_CompositorFrameSwapped::ID: | 865 case BrowserPluginMsg_CompositorFrameSwapped::ID: |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 | 906 |
| 1032 BrowserPluginHostMsg_ResizeGuest_Params params; | 907 BrowserPluginHostMsg_ResizeGuest_Params params; |
| 1033 PopulateResizeGuestParameters(¶ms, plugin_rect(), false); | 908 PopulateResizeGuestParameters(¶ms, plugin_rect(), false); |
| 1034 paint_ack_received_ = false; | 909 paint_ack_received_ = false; |
| 1035 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( | 910 browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( |
| 1036 render_view_routing_id_, | 911 render_view_routing_id_, |
| 1037 guest_instance_id_, | 912 guest_instance_id_, |
| 1038 params)); | 913 params)); |
| 1039 } | 914 } |
| 1040 | 915 |
| 1041 void BrowserPlugin::SwapDamageBuffers() { | |
| 1042 current_damage_buffer_.reset(pending_damage_buffer_.release()); | |
| 1043 paint_ack_received_ = true; | |
| 1044 } | |
| 1045 | |
| 1046 void BrowserPlugin::PopulateResizeGuestParameters( | 916 void BrowserPlugin::PopulateResizeGuestParameters( |
| 1047 BrowserPluginHostMsg_ResizeGuest_Params* params, | 917 BrowserPluginHostMsg_ResizeGuest_Params* params, |
| 1048 const gfx::Rect& view_rect, | 918 const gfx::Rect& view_rect, |
| 1049 bool needs_repaint) { | 919 bool needs_repaint) { |
| 1050 params->size_changed = true; | 920 params->size_changed = true; |
| 1051 params->view_rect = view_rect; | 921 params->view_rect = view_rect; |
| 1052 params->repaint = needs_repaint; | 922 params->repaint = needs_repaint; |
| 1053 params->scale_factor = GetDeviceScaleFactor(); | 923 params->scale_factor = GetDeviceScaleFactor(); |
| 1054 if (last_device_scale_factor_ != params->scale_factor){ | 924 if (last_device_scale_factor_ != params->scale_factor){ |
| 1055 params->repaint = true; | 925 params->repaint = true; |
| 1056 last_device_scale_factor_ = params->scale_factor; | 926 last_device_scale_factor_ = params->scale_factor; |
| 1057 } | 927 } |
| 1058 | |
| 1059 // In HW compositing mode, we do not need a damage buffer. | |
| 1060 if (compositing_enabled_) | |
| 1061 return; | |
| 1062 | |
| 1063 const size_t stride = skia::PlatformCanvasStrideForWidth(view_rect.width()); | |
| 1064 // Make sure the size of the damage buffer is at least four bytes so that we | |
| 1065 // can fit in a magic word to verify that the memory is shared correctly. | |
| 1066 size_t size = | |
| 1067 std::max(sizeof(unsigned int), | |
| 1068 static_cast<size_t>(view_rect.height() * | |
| 1069 stride * | |
| 1070 GetDeviceScaleFactor() * | |
| 1071 GetDeviceScaleFactor())); | |
| 1072 | |
| 1073 params->damage_buffer_size = size; | |
| 1074 pending_damage_buffer_.reset( | |
| 1075 CreateDamageBuffer(size, ¶ms->damage_buffer_handle)); | |
| 1076 if (!pending_damage_buffer_) | |
| 1077 NOTREACHED(); | |
| 1078 params->damage_buffer_sequence_id = ++damage_buffer_sequence_id_; | |
| 1079 } | 928 } |
| 1080 | 929 |
| 1081 void BrowserPlugin::GetDamageBufferWithSizeParams( | 930 void BrowserPlugin::GetSizeParams( |
| 1082 BrowserPluginHostMsg_AutoSize_Params* auto_size_params, | 931 BrowserPluginHostMsg_AutoSize_Params* auto_size_params, |
| 1083 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, | 932 BrowserPluginHostMsg_ResizeGuest_Params* resize_guest_params, |
| 1084 bool needs_repaint) { | 933 bool needs_repaint) { |
| 1085 if (auto_size_params) { | 934 if (auto_size_params) { |
| 1086 PopulateAutoSizeParameters(auto_size_params, GetAutoSizeAttribute()); | 935 PopulateAutoSizeParameters(auto_size_params, GetAutoSizeAttribute()); |
| 1087 } else { | 936 } else { |
| 1088 max_auto_size_ = gfx::Size(); | 937 max_auto_size_ = gfx::Size(); |
| 1089 } | 938 } |
| 1090 gfx::Size view_size = (auto_size_params && auto_size_params->enable) ? | 939 gfx::Size view_size = (auto_size_params && auto_size_params->enable) ? |
| 1091 auto_size_params->max_size : gfx::Size(width(), height()); | 940 auto_size_params->max_size : gfx::Size(width(), height()); |
| 1092 if (view_size.IsEmpty()) | 941 if (view_size.IsEmpty()) |
| 1093 return; | 942 return; |
| 1094 paint_ack_received_ = false; | 943 paint_ack_received_ = false; |
| 1095 gfx::Rect view_rect = gfx::Rect(plugin_rect_.origin(), view_size); | 944 gfx::Rect view_rect = gfx::Rect(plugin_rect_.origin(), view_size); |
| 1096 PopulateResizeGuestParameters(resize_guest_params, view_rect, needs_repaint); | 945 PopulateResizeGuestParameters(resize_guest_params, view_rect, needs_repaint); |
| 1097 } | 946 } |
| 1098 | 947 |
| 1099 #if defined(OS_POSIX) | |
| 1100 base::SharedMemory* BrowserPlugin::CreateDamageBuffer( | |
| 1101 const size_t size, | |
| 1102 base::SharedMemoryHandle* damage_buffer_handle) { | |
| 1103 scoped_ptr<base::SharedMemory> shared_buf( | |
| 1104 content::RenderThread::Get()->HostAllocateSharedMemoryBuffer( | |
| 1105 size).release()); | |
| 1106 | |
| 1107 if (shared_buf) { | |
| 1108 if (shared_buf->Map(size)) { | |
| 1109 // Insert the magic word. | |
| 1110 *static_cast<unsigned int*>(shared_buf->memory()) = 0xdeadbeef; | |
| 1111 shared_buf->ShareToProcess(base::GetCurrentProcessHandle(), | |
| 1112 damage_buffer_handle); | |
| 1113 return shared_buf.release(); | |
| 1114 } | |
| 1115 } | |
| 1116 NOTREACHED(); | |
| 1117 return NULL; | |
| 1118 } | |
| 1119 #elif defined(OS_WIN) | |
| 1120 base::SharedMemory* BrowserPlugin::CreateDamageBuffer( | |
| 1121 const size_t size, | |
| 1122 base::SharedMemoryHandle* damage_buffer_handle) { | |
| 1123 scoped_ptr<base::SharedMemory> shared_buf(new base::SharedMemory()); | |
| 1124 | |
| 1125 if (!shared_buf->CreateAndMapAnonymous(size)) { | |
| 1126 NOTREACHED() << "Buffer allocation failed"; | |
| 1127 return NULL; | |
| 1128 } | |
| 1129 | |
| 1130 // Insert the magic word. | |
| 1131 *static_cast<unsigned int*>(shared_buf->memory()) = 0xdeadbeef; | |
| 1132 if (shared_buf->ShareToProcess(base::GetCurrentProcessHandle(), | |
| 1133 damage_buffer_handle)) | |
| 1134 return shared_buf.release(); | |
| 1135 NOTREACHED(); | |
| 1136 return NULL; | |
| 1137 } | |
| 1138 #endif | |
| 1139 | |
| 1140 void BrowserPlugin::updateFocus(bool focused) { | 948 void BrowserPlugin::updateFocus(bool focused) { |
| 1141 plugin_focused_ = focused; | 949 plugin_focused_ = focused; |
| 1142 UpdateGuestFocusState(); | 950 UpdateGuestFocusState(); |
| 1143 } | 951 } |
| 1144 | 952 |
| 1145 void BrowserPlugin::updateVisibility(bool visible) { | 953 void BrowserPlugin::updateVisibility(bool visible) { |
| 1146 if (visible_ == visible) | 954 if (visible_ == visible) |
| 1147 return; | 955 return; |
| 1148 | 956 |
| 1149 visible_ = visible; | 957 visible_ = visible; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1342 const blink::WebMouseEvent& event) { | 1150 const blink::WebMouseEvent& event) { |
| 1343 browser_plugin_manager()->Send( | 1151 browser_plugin_manager()->Send( |
| 1344 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, | 1152 new BrowserPluginHostMsg_HandleInputEvent(render_view_routing_id_, |
| 1345 guest_instance_id_, | 1153 guest_instance_id_, |
| 1346 plugin_rect_, | 1154 plugin_rect_, |
| 1347 &event)); | 1155 &event)); |
| 1348 return true; | 1156 return true; |
| 1349 } | 1157 } |
| 1350 | 1158 |
| 1351 } // namespace content | 1159 } // namespace content |
| OLD | NEW |