Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/browser/renderer_host/render_widget_host_impl.h" | 5 #include "content/browser/renderer_host/render_widget_host_impl.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include <set> | 9 #include <set> |
| 10 #include <tuple> | 10 #include <tuple> |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 565 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDisambiguationPopup, | 565 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDisambiguationPopup, |
| 566 OnShowDisambiguationPopup) | 566 OnShowDisambiguationPopup) |
| 567 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged, | 567 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged, |
| 568 OnSelectionBoundsChanged) | 568 OnSelectionBoundsChanged) |
| 569 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged, | 569 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged, |
| 570 OnImeCompositionRangeChanged) | 570 OnImeCompositionRangeChanged) |
| 571 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames, OnSetNeedsBeginFrames) | 571 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames, OnSetNeedsBeginFrames) |
| 572 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched) | 572 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched) |
| 573 IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging) | 573 IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging) |
| 574 IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) | 574 IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) |
| 575 IPC_MESSAGE_HANDLER(ViewHostMsg_FrameSwapMessages, | |
| 576 OnFrameSwapMessagesReceived) | |
| 575 IPC_MESSAGE_UNHANDLED(handled = false) | 577 IPC_MESSAGE_UNHANDLED(handled = false) |
| 576 IPC_END_MESSAGE_MAP() | 578 IPC_END_MESSAGE_MAP() |
| 577 | 579 |
| 578 if (!handled && input_router_ && input_router_->OnMessageReceived(msg)) | 580 if (!handled && input_router_ && input_router_->OnMessageReceived(msg)) |
| 579 return true; | 581 return true; |
| 580 | 582 |
| 581 if (!handled && view_ && view_->OnMessageReceived(msg)) | 583 if (!handled && view_ && view_->OnMessageReceived(msg)) |
| 582 return true; | 584 return true; |
| 583 | 585 |
| 584 return handled; | 586 return handled; |
| (...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1567 | 1569 |
| 1568 void RenderWidgetHostImpl::OnUpdateDragCursor(WebDragOperation current_op) { | 1570 void RenderWidgetHostImpl::OnUpdateDragCursor(WebDragOperation current_op) { |
| 1569 if (delegate_ && delegate_->OnUpdateDragCursor()) | 1571 if (delegate_ && delegate_->OnUpdateDragCursor()) |
| 1570 return; | 1572 return; |
| 1571 | 1573 |
| 1572 RenderViewHostDelegateView* view = delegate_->GetDelegateView(); | 1574 RenderViewHostDelegateView* view = delegate_->GetDelegateView(); |
| 1573 if (view) | 1575 if (view) |
| 1574 view->UpdateDragCursor(current_op); | 1576 view->UpdateDragCursor(current_op); |
| 1575 } | 1577 } |
| 1576 | 1578 |
| 1579 void RenderWidgetHostImpl::OnFrameSwapMessagesReceived( | |
| 1580 uint32_t frame_token, | |
| 1581 std::vector<IPC::Message> messages) { | |
| 1582 // We will never receive messages for tokens smaller than |frame_token| so | |
| 1583 // remove them from the queue. | |
| 1584 while (queued_tokens_.size() && queued_tokens_.front() < frame_token) | |
|
Fady Samuel
2017/03/31 16:45:14
Why would the current frame_token not be at the fr
Saman Sami
2017/04/03 19:22:28
If we assume the renderer->browser connection is r
| |
| 1585 queued_tokens_.pop_front(); | |
| 1586 | |
| 1587 // If there are no tokens queued, queue |messages| so it can be processed | |
| 1588 // once a matching token arrives. | |
| 1589 if (queued_tokens_.empty()) { | |
| 1590 queued_messages_.push_back( | |
| 1591 std::make_pair(frame_token, std::move(messages))); | |
| 1592 return; | |
| 1593 } | |
| 1594 | |
| 1595 // If the first element of |queued_tokens_| matches |frame_token|, | |
| 1596 // process |messages| immediately. | |
| 1597 if (queued_tokens_.front() == frame_token) { | |
| 1598 queued_tokens_.pop_front(); | |
| 1599 ProcessSwapMessages(std::move(messages)); | |
| 1600 return; | |
| 1601 } | |
| 1602 | |
| 1603 // The first element of |queued_tokens_| is larger than |frame_token|. | |
| 1604 // Discard |messages| because we will never receive |frame_token| in the | |
| 1605 // future. | |
| 1606 } | |
| 1607 | |
| 1577 void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status, | 1608 void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status, |
| 1578 int exit_code) { | 1609 int exit_code) { |
| 1579 if (!renderer_initialized_) | 1610 if (!renderer_initialized_) |
| 1580 return; | 1611 return; |
| 1581 | 1612 |
| 1582 // Clear this flag so that we can ask the next renderer for composition | 1613 // Clear this flag so that we can ask the next renderer for composition |
| 1583 // updates. | 1614 // updates. |
| 1584 monitoring_composition_info_ = false; | 1615 monitoring_composition_info_ = false; |
| 1585 | 1616 |
| 1586 // Clearing this flag causes us to re-create the renderer when recovering | 1617 // Clearing this flag causes us to re-create the renderer when recovering |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1851 messages_to_deliver_with_frame.swap(std::get<3>(param)); | 1882 messages_to_deliver_with_frame.swap(std::get<3>(param)); |
| 1852 | 1883 |
| 1853 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { | 1884 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
| 1854 if (view_) | 1885 if (view_) |
| 1855 view_->DidCreateNewRendererCompositorFrameSink(); | 1886 view_->DidCreateNewRendererCompositorFrameSink(); |
| 1856 last_compositor_frame_sink_id_ = compositor_frame_sink_id; | 1887 last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
| 1857 } | 1888 } |
| 1858 | 1889 |
| 1859 SubmitCompositorFrame(local_surface_id, std::move(frame)); | 1890 SubmitCompositorFrame(local_surface_id, std::move(frame)); |
| 1860 | 1891 |
| 1861 RenderProcessHost* rph = GetProcess(); | |
| 1862 for (std::vector<IPC::Message>::const_iterator i = | |
| 1863 messages_to_deliver_with_frame.begin(); | |
| 1864 i != messages_to_deliver_with_frame.end(); | |
| 1865 ++i) { | |
| 1866 rph->OnMessageReceived(*i); | |
| 1867 if (i->dispatch_error()) | |
| 1868 rph->OnBadMessageReceived(*i); | |
| 1869 } | |
| 1870 messages_to_deliver_with_frame.clear(); | |
| 1871 | |
| 1872 return true; | 1892 return true; |
| 1873 } | 1893 } |
| 1874 | 1894 |
| 1875 void RenderWidgetHostImpl::OnBeginFrameDidNotSwap( | 1895 void RenderWidgetHostImpl::OnBeginFrameDidNotSwap( |
| 1876 const cc::BeginFrameAck& ack) { | 1896 const cc::BeginFrameAck& ack) { |
| 1877 if (ack.sequence_number < cc::BeginFrameArgs::kStartingFrameNumber) { | 1897 if (ack.sequence_number < cc::BeginFrameArgs::kStartingFrameNumber) { |
| 1878 // Received an invalid ack, renderer misbehaved. | 1898 // Received an invalid ack, renderer misbehaved. |
| 1879 bad_message::ReceivedBadMessage( | 1899 bad_message::ReceivedBadMessage( |
| 1880 GetProcess(), bad_message::RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP); | 1900 GetProcess(), bad_message::RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP); |
| 1881 return; | 1901 return; |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2600 (frame_size != last_frame_size_ || | 2620 (frame_size != last_frame_size_ || |
| 2601 device_scale_factor != last_device_scale_factor_)) { | 2621 device_scale_factor != last_device_scale_factor_)) { |
| 2602 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." | 2622 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." |
| 2603 << " Expected: size=" << last_frame_size_.ToString() | 2623 << " Expected: size=" << last_frame_size_.ToString() |
| 2604 << ",scale=" << last_device_scale_factor_ | 2624 << ",scale=" << last_device_scale_factor_ |
| 2605 << " Received: size=" << frame_size.ToString() | 2625 << " Received: size=" << frame_size.ToString() |
| 2606 << ",scale=" << device_scale_factor; | 2626 << ",scale=" << device_scale_factor; |
| 2607 return; | 2627 return; |
| 2608 } | 2628 } |
| 2609 | 2629 |
| 2630 uint32_t frame_token = frame.metadata.frame_token; | |
| 2631 | |
| 2610 last_local_surface_id_ = local_surface_id; | 2632 last_local_surface_id_ = local_surface_id; |
| 2611 last_frame_size_ = frame_size; | 2633 last_frame_size_ = frame_size; |
| 2612 last_device_scale_factor_ = device_scale_factor; | 2634 last_device_scale_factor_ = device_scale_factor; |
| 2613 | 2635 |
| 2614 last_received_content_source_id_ = frame.metadata.content_source_id; | 2636 last_received_content_source_id_ = frame.metadata.content_source_id; |
| 2615 | 2637 |
| 2616 if (frame.metadata.begin_frame_ack.sequence_number < | 2638 if (frame.metadata.begin_frame_ack.sequence_number < |
| 2617 cc::BeginFrameArgs::kStartingFrameNumber) { | 2639 cc::BeginFrameArgs::kStartingFrameNumber) { |
| 2618 // Received an invalid ack, renderer misbehaved. | 2640 // Received an invalid ack, renderer misbehaved. |
| 2619 bad_message::ReceivedBadMessage( | 2641 bad_message::ReceivedBadMessage( |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2650 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); | 2672 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
| 2651 SendReclaimCompositorResources(true /* is_swap_ack */, resources); | 2673 SendReclaimCompositorResources(true /* is_swap_ack */, resources); |
| 2652 } | 2674 } |
| 2653 | 2675 |
| 2654 // After navigation, if a frame belonging to the new page is received, stop | 2676 // After navigation, if a frame belonging to the new page is received, stop |
| 2655 // the timer that triggers clearing the graphics of the last page. | 2677 // the timer that triggers clearing the graphics of the last page. |
| 2656 if (last_received_content_source_id_ >= current_content_source_id_ && | 2678 if (last_received_content_source_id_ >= current_content_source_id_ && |
| 2657 new_content_rendering_timeout_->IsRunning()) { | 2679 new_content_rendering_timeout_->IsRunning()) { |
| 2658 new_content_rendering_timeout_->Stop(); | 2680 new_content_rendering_timeout_->Stop(); |
| 2659 } | 2681 } |
| 2682 | |
| 2683 if (frame_token) | |
| 2684 DidProcessFrame(frame_token); | |
| 2685 } | |
| 2686 | |
| 2687 void RenderWidgetHostImpl::DidProcessFrame(uint32_t frame_token) { | |
| 2688 // We won't receive frames with tokens smaller than |frame_token| in the | |
| 2689 // future. Get rid of all messages queued for such frames. | |
| 2690 while (queued_messages_.size() && | |
| 2691 queued_messages_.front().first < frame_token) | |
|
Fady Samuel
2017/03/31 16:45:14
This seems like a bug to get into this state? If n
Saman Sami
2017/04/03 19:22:28
If a frame was dropped (for example, on gpu crash)
| |
| 2692 queued_messages_.pop_front(); | |
| 2693 | |
| 2694 // If there are no queued messages, add |frame_token| to |queued_tokens_| so | |
| 2695 // that we can process its messages once they arrive. | |
| 2696 if (queued_messages_.empty()) { | |
| 2697 queued_tokens_.push_back(frame_token); | |
| 2698 return; | |
| 2699 } | |
| 2700 | |
| 2701 // If the first element of |queued_messages_| belongs to |frame_token|, | |
| 2702 // process the queued messages. | |
| 2703 if (queued_messages_.front().first == frame_token) { | |
| 2704 ProcessSwapMessages(std::move(queued_messages_.front().second)); | |
| 2705 queued_messages_.pop_front(); | |
| 2706 return; | |
| 2707 } | |
| 2708 | |
| 2709 // The first element of |queued_messages_| belongs to a larger frame token. | |
| 2710 // We discard |frame_token| because its messages will never arrive. | |
|
Fady Samuel
2017/03/31 16:45:14
A well-behaved renderer should never get into this
Saman Sami
2017/04/03 19:22:28
If we assume the renderer->browser connection is r
| |
| 2711 } | |
| 2712 | |
| 2713 void RenderWidgetHostImpl::ProcessSwapMessages( | |
| 2714 std::vector<IPC::Message> messages) { | |
| 2715 RenderProcessHost* rph = GetProcess(); | |
| 2716 for (std::vector<IPC::Message>::const_iterator i = messages.begin(); | |
| 2717 i != messages.end(); ++i) { | |
| 2718 rph->OnMessageReceived(*i); | |
| 2719 if (i->dispatch_error()) | |
| 2720 rph->OnBadMessageReceived(*i); | |
| 2721 } | |
| 2660 } | 2722 } |
| 2661 | 2723 |
| 2662 } // namespace content | 2724 } // namespace content |
| OLD | NEW |