| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/renderer_host/render_widget_host.h" | 5 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/histogram.h" | 8 #include "base/histogram.h" |
| 9 #include "base/keyboard_codes.h" | 9 #include "base/keyboard_codes.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 Destroy(); | 117 Destroy(); |
| 118 } | 118 } |
| 119 | 119 |
| 120 void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { | 120 void RenderWidgetHost::OnMessageReceived(const IPC::Message &msg) { |
| 121 bool msg_is_ok = true; | 121 bool msg_is_ok = true; |
| 122 IPC_BEGIN_MESSAGE_MAP_EX(RenderWidgetHost, msg, msg_is_ok) | 122 IPC_BEGIN_MESSAGE_MAP_EX(RenderWidgetHost, msg, msg_is_ok) |
| 123 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady) | 123 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewReady, OnMsgRenderViewReady) |
| 124 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone) | 124 IPC_MESSAGE_HANDLER(ViewHostMsg_RenderViewGone, OnMsgRenderViewGone) |
| 125 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) | 125 IPC_MESSAGE_HANDLER(ViewHostMsg_Close, OnMsgClose) |
| 126 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) | 126 IPC_MESSAGE_HANDLER(ViewHostMsg_RequestMove, OnMsgRequestMove) |
| 127 IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnMsgUpdateRect) | 127 IPC_MESSAGE_HANDLER(ViewHostMsg_PaintRect, OnMsgPaintRect) |
| 128 IPC_MESSAGE_HANDLER(ViewHostMsg_ScrollRect, OnMsgScrollRect) |
| 128 IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) | 129 IPC_MESSAGE_HANDLER(ViewHostMsg_HandleInputEvent_ACK, OnMsgInputEventAck) |
| 129 IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) | 130 IPC_MESSAGE_HANDLER(ViewHostMsg_Focus, OnMsgFocus) |
| 130 IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) | 131 IPC_MESSAGE_HANDLER(ViewHostMsg_Blur, OnMsgBlur) |
| 131 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) | 132 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeChanged, OnMsgFocusedNodeChanged) |
| 132 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) | 133 IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnMsgSetCursor) |
| 133 IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) | 134 IPC_MESSAGE_HANDLER(ViewHostMsg_ImeUpdateStatus, OnMsgImeUpdateStatus) |
| 134 #if defined(OS_LINUX) | 135 #if defined(OS_LINUX) |
| 135 IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer, | 136 IPC_MESSAGE_HANDLER(ViewHostMsg_CreatePluginContainer, |
| 136 OnMsgCreatePluginContainer) | 137 OnMsgCreatePluginContainer) |
| 137 IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer, | 138 IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 repaint_ack_pending_ = true; | 292 repaint_ack_pending_ = true; |
| 292 Send(new ViewMsg_Repaint(routing_id_, current_size_)); | 293 Send(new ViewMsg_Repaint(routing_id_, current_size_)); |
| 293 } | 294 } |
| 294 | 295 |
| 295 // When we have asked the RenderWidget to resize, and we are still waiting on | 296 // When we have asked the RenderWidget to resize, and we are still waiting on |
| 296 // a response, block for a little while to see if we can't get a response | 297 // a response, block for a little while to see if we can't get a response |
| 297 // before returning the old (incorrectly sized) backing store. | 298 // before returning the old (incorrectly sized) backing store. |
| 298 if (resize_ack_pending_ || !backing_store) { | 299 if (resize_ack_pending_ || !backing_store) { |
| 299 IPC::Message msg; | 300 IPC::Message msg; |
| 300 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); | 301 TimeDelta max_delay = TimeDelta::FromMilliseconds(kPaintMsgTimeoutMS); |
| 301 if (process_->WaitForUpdateMsg(routing_id_, max_delay, &msg)) { | 302 if (process_->WaitForPaintMsg(routing_id_, max_delay, &msg)) { |
| 302 ViewHostMsg_UpdateRect::Dispatch( | 303 ViewHostMsg_PaintRect::Dispatch( |
| 303 &msg, this, &RenderWidgetHost::OnMsgUpdateRect); | 304 &msg, this, &RenderWidgetHost::OnMsgPaintRect); |
| 304 backing_store = BackingStoreManager::GetBackingStore(this, current_size_); | 305 backing_store = BackingStoreManager::GetBackingStore(this, current_size_); |
| 305 } | 306 } |
| 306 } | 307 } |
| 307 | 308 |
| 308 return backing_store; | 309 return backing_store; |
| 309 } | 310 } |
| 310 | 311 |
| 311 BackingStore* RenderWidgetHost::AllocBackingStore(const gfx::Size& size) { | 312 BackingStore* RenderWidgetHost::AllocBackingStore(const gfx::Size& size) { |
| 312 if (!view_) | 313 if (!view_) |
| 313 return NULL; | 314 return NULL; |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 } | 611 } |
| 611 | 612 |
| 612 void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) { | 613 void RenderWidgetHost::OnMsgRequestMove(const gfx::Rect& pos) { |
| 613 // Note that we ignore the position. | 614 // Note that we ignore the position. |
| 614 if (view_) { | 615 if (view_) { |
| 615 view_->SetSize(pos.size()); | 616 view_->SetSize(pos.size()); |
| 616 Send(new ViewMsg_Move_ACK(routing_id_)); | 617 Send(new ViewMsg_Move_ACK(routing_id_)); |
| 617 } | 618 } |
| 618 } | 619 } |
| 619 | 620 |
| 620 void RenderWidgetHost::OnMsgUpdateRect( | 621 void RenderWidgetHost::OnMsgPaintRect( |
| 621 const ViewHostMsg_UpdateRect_Params& params) { | 622 const ViewHostMsg_PaintRect_Params& params) { |
| 622 TimeTicks paint_start = TimeTicks::Now(); | 623 TimeTicks paint_start = TimeTicks::Now(); |
| 623 | 624 |
| 624 // Update our knowledge of the RenderWidget's size. | 625 // Update our knowledge of the RenderWidget's size. |
| 625 current_size_ = params.view_size; | 626 current_size_ = params.view_size; |
| 626 | 627 |
| 627 bool is_resize_ack = | 628 bool is_resize_ack = |
| 628 ViewHostMsg_UpdateRect_Flags::is_resize_ack(params.flags); | 629 ViewHostMsg_PaintRect_Flags::is_resize_ack(params.flags); |
| 629 | 630 |
| 630 // resize_ack_pending_ needs to be cleared before we call DidPaintRect, since | 631 // resize_ack_pending_ needs to be cleared before we call DidPaintRect, since |
| 631 // that will end up reaching GetBackingStore. | 632 // that will end up reaching GetBackingStore. |
| 632 if (is_resize_ack) { | 633 if (is_resize_ack) { |
| 633 DCHECK(resize_ack_pending_); | 634 DCHECK(resize_ack_pending_); |
| 634 resize_ack_pending_ = false; | 635 resize_ack_pending_ = false; |
| 635 in_flight_size_.SetSize(0, 0); | 636 in_flight_size_.SetSize(0, 0); |
| 636 } | 637 } |
| 637 | 638 |
| 638 bool is_repaint_ack = | 639 bool is_repaint_ack = |
| 639 ViewHostMsg_UpdateRect_Flags::is_repaint_ack(params.flags); | 640 ViewHostMsg_PaintRect_Flags::is_repaint_ack(params.flags); |
| 640 if (is_repaint_ack) { | 641 if (is_repaint_ack) { |
| 641 repaint_ack_pending_ = false; | 642 repaint_ack_pending_ = false; |
| 642 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; | 643 TimeDelta delta = TimeTicks::Now() - repaint_start_time_; |
| 643 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta); | 644 UMA_HISTOGRAM_TIMES("MPArch.RWH_RepaintDelta", delta); |
| 644 } | 645 } |
| 645 | 646 |
| 646 DCHECK(!params.bitmap_rect.IsEmpty()); | 647 DCHECK(!params.bitmap_rect.IsEmpty()); |
| 647 DCHECK(!params.view_size.IsEmpty()); | 648 DCHECK(!params.view_size.IsEmpty()); |
| 648 | 649 |
| 649 const size_t size = params.bitmap_rect.height() * | 650 const size_t size = params.bitmap_rect.height() * |
| 650 params.bitmap_rect.width() * 4; | 651 params.bitmap_rect.width() * 4; |
| 651 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); | 652 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); |
| 652 if (dib) { | 653 if (dib) { |
| 653 if (dib->size() < size) { | 654 if (dib->size() < size) { |
| 654 DLOG(WARNING) << "Transport DIB too small for given rectangle"; | 655 DLOG(WARNING) << "Transport DIB too small for given rectangle"; |
| 655 process()->ReceivedBadMessage(ViewHostMsg_UpdateRect__ID); | 656 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); |
| 656 } else { | 657 } else { |
| 657 // Scroll the backing store. | |
| 658 if (!params.scroll_rect.IsEmpty()) { | |
| 659 ScrollBackingStoreRect(params.dx, params.dy, | |
| 660 params.scroll_rect, | |
| 661 params.view_size); | |
| 662 } | |
| 663 | |
| 664 // Paint the backing store. This will update it with the renderer-supplied | 658 // Paint the backing store. This will update it with the renderer-supplied |
| 665 // bits. The view will read out of the backing store later to actually | 659 // bits. The view will read out of the backing store later to actually |
| 666 // draw to the screen. | 660 // draw to the screen. |
| 667 PaintBackingStoreRect(dib, params.bitmap_rect, params.copy_rects, | 661 PaintBackingStoreRect(dib, params.bitmap_rect, params.update_rects, |
| 668 params.view_size); | 662 params.view_size); |
| 669 } | 663 } |
| 670 } | 664 } |
| 671 | 665 |
| 672 // ACK early so we can prefetch the next PaintRect if there is a next one. | 666 // ACK early so we can prefetch the next PaintRect if there is a next one. |
| 673 // This must be done AFTER we're done painting with the bitmap supplied by the | 667 // This must be done AFTER we're done painting with the bitmap supplied by the |
| 674 // renderer. This ACK is a signal to the renderer that the backing store can | 668 // renderer. This ACK is a signal to the renderer that the backing store can |
| 675 // be re-used, so the bitmap may be invalid after this call. | 669 // be re-used, so the bitmap may be invalid after this call. |
| 676 Send(new ViewMsg_UpdateRect_ACK(routing_id_)); | 670 Send(new ViewMsg_PaintRect_ACK(routing_id_)); |
| 677 | 671 |
| 678 // We don't need to update the view if the view is hidden. We must do this | 672 // We don't need to update the view if the view is hidden. We must do this |
| 679 // early return after the ACK is sent, however, or the renderer will not send | 673 // early return after the ACK is sent, however, or the renderer will not send |
| 680 // us more data. | 674 // us more data. |
| 681 if (is_hidden_) | 675 if (is_hidden_) |
| 682 return; | 676 return; |
| 683 | 677 |
| 684 // Now paint the view. Watch out: it might be destroyed already. | 678 // Now paint the view. Watch out: it might be destroyed already. |
| 685 if (view_) { | 679 if (view_) { |
| 686 view_->MovePluginWindows(params.plugin_window_moves); | 680 view_->MovePluginWindows(params.plugin_window_moves); |
| 687 view_being_painted_ = true; | 681 view_being_painted_ = true; |
| 688 if (!params.scroll_rect.IsEmpty()) { | 682 view_->DidPaintRect(params.bitmap_rect); |
| 689 view_->DidScrollBackingStoreRect(params.scroll_rect, | |
| 690 params.dx, | |
| 691 params.dy); | |
| 692 } | |
| 693 view_->DidPaintBackingStoreRects(params.copy_rects); | |
| 694 view_being_painted_ = false; | 683 view_being_painted_ = false; |
| 695 } | 684 } |
| 696 | 685 |
| 697 if (paint_observer_.get()) | 686 if (paint_observer_.get()) |
| 698 paint_observer_->RenderWidgetHostDidPaint(this); | 687 paint_observer_->RenderWidgetHostDidPaint(this); |
| 699 | 688 |
| 700 // If we got a resize ack, then perhaps we have another resize to send? | 689 // If we got a resize ack, then perhaps we have another resize to send? |
| 701 if (is_resize_ack && view_) { | 690 if (is_resize_ack && view_) { |
| 702 gfx::Rect view_bounds = view_->GetViewBounds(); | 691 gfx::Rect view_bounds = view_->GetViewBounds(); |
| 703 if (current_size_.width() != view_bounds.width() || | 692 if (current_size_.width() != view_bounds.width() || |
| 704 current_size_.height() != view_bounds.height()) { | 693 current_size_.height() != view_bounds.height()) { |
| 705 WasResized(); | 694 WasResized(); |
| 706 } | 695 } |
| 707 } | 696 } |
| 708 | 697 |
| 709 if (painting_observer_) | 698 if (painting_observer_) |
| 710 painting_observer_->WidgetDidUpdateBackingStore(this); | 699 painting_observer_->WidgetDidUpdateBackingStore(this); |
| 711 | 700 |
| 712 // Log the time delta for processing a paint message. | 701 // Log the time delta for processing a paint message. |
| 713 TimeDelta delta = TimeTicks::Now() - paint_start; | 702 TimeDelta delta = TimeTicks::Now() - paint_start; |
| 714 UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgUpdateRect", delta); | 703 UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgPaintRect", delta); |
| 704 } |
| 705 |
| 706 void RenderWidgetHost::OnMsgScrollRect( |
| 707 const ViewHostMsg_ScrollRect_Params& params) { |
| 708 TimeTicks scroll_start = TimeTicks::Now(); |
| 709 |
| 710 DCHECK(!params.view_size.IsEmpty()); |
| 711 |
| 712 const size_t size = params.bitmap_rect.height() * |
| 713 params.bitmap_rect.width() * 4; |
| 714 TransportDIB* dib = process_->GetTransportDIB(params.bitmap); |
| 715 if (dib) { |
| 716 if (dib->size() < size) { |
| 717 LOG(WARNING) << "Transport DIB too small for given rectangle"; |
| 718 process()->ReceivedBadMessage(ViewHostMsg_PaintRect__ID); |
| 719 } else { |
| 720 // Scroll the backing store. |
| 721 ScrollBackingStoreRect(dib, params.bitmap_rect, |
| 722 params.dx, params.dy, |
| 723 params.clip_rect, params.view_size); |
| 724 } |
| 725 } |
| 726 |
| 727 // ACK early so we can prefetch the next ScrollRect if there is a next one. |
| 728 // This must be done AFTER we're done painting with the bitmap supplied by the |
| 729 // renderer. This ACK is a signal to the renderer that the backing store can |
| 730 // be re-used, so the bitmap may be invalid after this call. |
| 731 Send(new ViewMsg_ScrollRect_ACK(routing_id_)); |
| 732 |
| 733 // We don't need to update the view if the view is hidden. We must do this |
| 734 // early return after the ACK is sent, however, or the renderer will not send |
| 735 // is more data. |
| 736 if (is_hidden_) |
| 737 return; |
| 738 |
| 739 // Paint the view. Watch out: it might be destroyed already. |
| 740 if (view_) { |
| 741 view_being_painted_ = true; |
| 742 view_->MovePluginWindows(params.plugin_window_moves); |
| 743 view_->DidScrollRect(params.clip_rect, params.dx, params.dy); |
| 744 view_being_painted_ = false; |
| 745 } |
| 746 |
| 747 if (painting_observer_) |
| 748 painting_observer_->WidgetDidUpdateBackingStore(this); |
| 749 |
| 750 // Log the time delta for processing a scroll message. |
| 751 TimeDelta delta = TimeTicks::Now() - scroll_start; |
| 752 UMA_HISTOGRAM_TIMES("MPArch.RWH_OnMsgScrollRect", delta); |
| 715 } | 753 } |
| 716 | 754 |
| 717 void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) { | 755 void RenderWidgetHost::OnMsgInputEventAck(const IPC::Message& message) { |
| 718 // Log the time delta for processing an input event. | 756 // Log the time delta for processing an input event. |
| 719 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; | 757 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; |
| 720 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta); | 758 UMA_HISTOGRAM_TIMES("MPArch.RWH_InputEventDelta", delta); |
| 721 | 759 |
| 722 // Cancel pending hung renderer checks since the renderer is responsive. | 760 // Cancel pending hung renderer checks since the renderer is responsive. |
| 723 StopHangMonitorTimeout(); | 761 StopHangMonitorTimeout(); |
| 724 | 762 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 process_->GetHandle(), | 884 process_->GetHandle(), |
| 847 bitmap, bitmap_rect, copy_rects, | 885 bitmap, bitmap_rect, copy_rects, |
| 848 &needs_full_paint); | 886 &needs_full_paint); |
| 849 if (needs_full_paint) { | 887 if (needs_full_paint) { |
| 850 repaint_start_time_ = TimeTicks::Now(); | 888 repaint_start_time_ = TimeTicks::Now(); |
| 851 repaint_ack_pending_ = true; | 889 repaint_ack_pending_ = true; |
| 852 Send(new ViewMsg_Repaint(routing_id_, view_size)); | 890 Send(new ViewMsg_Repaint(routing_id_, view_size)); |
| 853 } | 891 } |
| 854 } | 892 } |
| 855 | 893 |
| 856 void RenderWidgetHost::ScrollBackingStoreRect(int dx, int dy, | 894 void RenderWidgetHost::ScrollBackingStoreRect(TransportDIB* bitmap, |
| 895 const gfx::Rect& bitmap_rect, |
| 896 int dx, int dy, |
| 857 const gfx::Rect& clip_rect, | 897 const gfx::Rect& clip_rect, |
| 858 const gfx::Size& view_size) { | 898 const gfx::Size& view_size) { |
| 859 if (is_hidden_) { | 899 if (is_hidden_) { |
| 860 // Don't bother updating the backing store when we're hidden. Just mark it | 900 // Don't bother updating the backing store when we're hidden. Just mark it |
| 861 // as being totally invalid. This will cause a complete repaint when the | 901 // as being totally invalid. This will cause a complete repaint when the |
| 862 // view is restored. | 902 // view is restored. |
| 863 needs_repainting_on_restore_ = true; | 903 needs_repainting_on_restore_ = true; |
| 864 return; | 904 return; |
| 865 } | 905 } |
| 866 | 906 |
| 867 // TODO(darin): do we need to do something else if our backing store is not | 907 // TODO(darin): do we need to do something else if our backing store is not |
| 868 // the same size as the advertised view? maybe we just assume there is a | 908 // the same size as the advertised view? maybe we just assume there is a |
| 869 // full paint on its way? | 909 // full paint on its way? |
| 870 BackingStore* backing_store = BackingStoreManager::Lookup(this); | 910 BackingStore* backing_store = BackingStoreManager::Lookup(this); |
| 871 if (!backing_store || (backing_store->size() != view_size)) | 911 if (!backing_store || (backing_store->size() != view_size)) |
| 872 return; | 912 return; |
| 873 backing_store->ScrollRect(dx, dy, clip_rect, view_size); | 913 backing_store->ScrollRect(process_->GetHandle(), bitmap, bitmap_rect, |
| 914 dx, dy, clip_rect, view_size); |
| 874 } | 915 } |
| 875 | 916 |
| 876 void RenderWidgetHost::ToggleSpellPanel(bool is_currently_visible) { | 917 void RenderWidgetHost::ToggleSpellPanel(bool is_currently_visible) { |
| 877 Send(new ViewMsg_ToggleSpellPanel(routing_id(), is_currently_visible)); | 918 Send(new ViewMsg_ToggleSpellPanel(routing_id(), is_currently_visible)); |
| 878 } | 919 } |
| 879 | 920 |
| 880 void RenderWidgetHost::Replace(const string16& word) { | 921 void RenderWidgetHost::Replace(const string16& word) { |
| 881 Send(new ViewMsg_Replace(routing_id_, word)); | 922 Send(new ViewMsg_Replace(routing_id_, word)); |
| 882 } | 923 } |
| 883 | 924 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 904 | 945 |
| 905 if (!processed) { | 946 if (!processed) { |
| 906 UnhandledKeyboardEvent(front_item); | 947 UnhandledKeyboardEvent(front_item); |
| 907 | 948 |
| 908 // WARNING: This RenderWidgetHost can be deallocated at this point | 949 // WARNING: This RenderWidgetHost can be deallocated at this point |
| 909 // (i.e. in the case of Ctrl+W, where the call to | 950 // (i.e. in the case of Ctrl+W, where the call to |
| 910 // UnhandledKeyboardEvent destroys this RenderWidgetHost). | 951 // UnhandledKeyboardEvent destroys this RenderWidgetHost). |
| 911 } | 952 } |
| 912 } | 953 } |
| 913 } | 954 } |
| OLD | NEW |