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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDisambiguationPopup, | 567 IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDisambiguationPopup, |
| 568 OnShowDisambiguationPopup) | 568 OnShowDisambiguationPopup) |
| 569 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged, | 569 IPC_MESSAGE_HANDLER(ViewHostMsg_SelectionBoundsChanged, |
| 570 OnSelectionBoundsChanged) | 570 OnSelectionBoundsChanged) |
| 571 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged, | 571 IPC_MESSAGE_HANDLER(InputHostMsg_ImeCompositionRangeChanged, |
| 572 OnImeCompositionRangeChanged) | 572 OnImeCompositionRangeChanged) |
| 573 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames, OnSetNeedsBeginFrames) | 573 IPC_MESSAGE_HANDLER(ViewHostMsg_SetNeedsBeginFrames, OnSetNeedsBeginFrames) |
| 574 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched) | 574 IPC_MESSAGE_HANDLER(ViewHostMsg_FocusedNodeTouched, OnFocusedNodeTouched) |
| 575 IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging) | 575 IPC_MESSAGE_HANDLER(DragHostMsg_StartDragging, OnStartDragging) |
| 576 IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) | 576 IPC_MESSAGE_HANDLER(DragHostMsg_UpdateDragCursor, OnUpdateDragCursor) |
| 577 IPC_MESSAGE_HANDLER(ViewHostMsg_FrameSwapMessages, | |
| 578 OnFrameSwapMessagesReceived) | |
| 577 IPC_MESSAGE_UNHANDLED(handled = false) | 579 IPC_MESSAGE_UNHANDLED(handled = false) |
| 578 IPC_END_MESSAGE_MAP() | 580 IPC_END_MESSAGE_MAP() |
| 579 | 581 |
| 580 if (!handled && input_router_ && input_router_->OnMessageReceived(msg)) | 582 if (!handled && input_router_ && input_router_->OnMessageReceived(msg)) |
| 581 return true; | 583 return true; |
| 582 | 584 |
| 583 if (!handled && view_ && view_->OnMessageReceived(msg)) | 585 if (!handled && view_ && view_->OnMessageReceived(msg)) |
| 584 return true; | 586 return true; |
| 585 | 587 |
| 586 return handled; | 588 return handled; |
| (...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1569 | 1571 |
| 1570 void RenderWidgetHostImpl::OnUpdateDragCursor(WebDragOperation current_op) { | 1572 void RenderWidgetHostImpl::OnUpdateDragCursor(WebDragOperation current_op) { |
| 1571 if (delegate_ && delegate_->OnUpdateDragCursor()) | 1573 if (delegate_ && delegate_->OnUpdateDragCursor()) |
| 1572 return; | 1574 return; |
| 1573 | 1575 |
| 1574 RenderViewHostDelegateView* view = delegate_->GetDelegateView(); | 1576 RenderViewHostDelegateView* view = delegate_->GetDelegateView(); |
| 1575 if (view) | 1577 if (view) |
| 1576 view->UpdateDragCursor(current_op); | 1578 view->UpdateDragCursor(current_op); |
| 1577 } | 1579 } |
| 1578 | 1580 |
| 1581 void RenderWidgetHostImpl::OnFrameSwapMessagesReceived( | |
| 1582 uint32_t frame_token, | |
| 1583 std::vector<IPC::Message> messages) { | |
| 1584 // Zero token is invalid. | |
| 1585 if (!frame_token) { | |
| 1586 bad_message::ReceivedBadMessage(GetProcess(), | |
| 1587 bad_message::RWH_INVALID_FRAME_TOKEN); | |
| 1588 return; | |
| 1589 } | |
| 1590 | |
| 1591 // Frame tokens always increase. | |
| 1592 if (queued_messages_.size() && frame_token <= queued_messages_.back().first) { | |
| 1593 bad_message::ReceivedBadMessage(GetProcess(), | |
| 1594 bad_message::RWH_INVALID_FRAME_TOKEN); | |
| 1595 return; | |
| 1596 } | |
| 1597 | |
| 1598 // If there are no tokens queued, queue |messages| so it can be processed | |
| 1599 // once a matching token arrives. | |
| 1600 if (queued_tokens_.empty()) { | |
| 1601 queued_messages_.push_back( | |
| 1602 std::make_pair(frame_token, std::move(messages))); | |
| 1603 return; | |
| 1604 } | |
| 1605 | |
| 1606 // The renderer did not send messages for smaller frame tokens. We kill it | |
| 1607 // because it's misbehaving. | |
| 1608 if (queued_tokens_.front() < frame_token) { | |
| 1609 bad_message::ReceivedBadMessage(GetProcess(), | |
| 1610 bad_message::RWH_INVALID_FRAME_TOKEN); | |
| 1611 return; | |
| 1612 } | |
| 1613 | |
| 1614 // If the first element of |queued_tokens_| matches |frame_token|, | |
| 1615 // process |messages| immediately. | |
| 1616 if (queued_tokens_.front() == frame_token) { | |
| 1617 queued_tokens_.pop_front(); | |
| 1618 ProcessSwapMessages(std::move(messages)); | |
| 1619 return; | |
| 1620 } | |
| 1621 | |
| 1622 // The first element of |queued_tokens_| is larger than |frame_token|. | |
| 1623 // Discard |messages| because we will never receive |frame_token| in the | |
| 1624 // future. | |
|
piman
2017/04/03 23:48:26
nit: shouldn't this be consistent with the queued_
Saman Sami
2017/04/03 23:56:01
I'm making the assumption that frames can be dropp
Saman Sami
2017/04/03 23:58:09
Maybe we should actually process the messages if t
piman
2017/04/04 00:08:11
Do you have a scenario in mind where frames get dr
Fady Samuel
2017/04/04 00:10:10
If the GPU process crashes, perhaps? Note that thi
Saman Sami
2017/04/04 00:13:51
Yes, GPU can crash before being able to send the t
Saman Sami
2017/04/04 00:16:17
If it makes sense to process the messages of frame
piman
2017/04/04 00:21:53
sgtm
| |
| 1625 } | |
| 1626 | |
| 1579 void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status, | 1627 void RenderWidgetHostImpl::RendererExited(base::TerminationStatus status, |
| 1580 int exit_code) { | 1628 int exit_code) { |
| 1581 if (!renderer_initialized_) | 1629 if (!renderer_initialized_) |
| 1582 return; | 1630 return; |
| 1583 | 1631 |
| 1584 // Clear this flag so that we can ask the next renderer for composition | 1632 // Clear this flag so that we can ask the next renderer for composition |
| 1585 // updates. | 1633 // updates. |
| 1586 monitoring_composition_info_ = false; | 1634 monitoring_composition_info_ = false; |
| 1587 | 1635 |
| 1588 // Clearing this flag causes us to re-create the renderer when recovering | 1636 // 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... | |
| 1853 messages_to_deliver_with_frame.swap(std::get<3>(param)); | 1901 messages_to_deliver_with_frame.swap(std::get<3>(param)); |
| 1854 | 1902 |
| 1855 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { | 1903 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
| 1856 if (view_) | 1904 if (view_) |
| 1857 view_->DidCreateNewRendererCompositorFrameSink(); | 1905 view_->DidCreateNewRendererCompositorFrameSink(); |
| 1858 last_compositor_frame_sink_id_ = compositor_frame_sink_id; | 1906 last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
| 1859 } | 1907 } |
| 1860 | 1908 |
| 1861 SubmitCompositorFrame(local_surface_id, std::move(frame)); | 1909 SubmitCompositorFrame(local_surface_id, std::move(frame)); |
| 1862 | 1910 |
| 1863 RenderProcessHost* rph = GetProcess(); | |
| 1864 for (std::vector<IPC::Message>::const_iterator i = | |
| 1865 messages_to_deliver_with_frame.begin(); | |
| 1866 i != messages_to_deliver_with_frame.end(); | |
| 1867 ++i) { | |
| 1868 rph->OnMessageReceived(*i); | |
| 1869 if (i->dispatch_error()) | |
| 1870 rph->OnBadMessageReceived(*i); | |
| 1871 } | |
| 1872 messages_to_deliver_with_frame.clear(); | |
| 1873 | |
| 1874 return true; | 1911 return true; |
| 1875 } | 1912 } |
| 1876 | 1913 |
| 1877 void RenderWidgetHostImpl::OnBeginFrameDidNotSwap( | 1914 void RenderWidgetHostImpl::OnBeginFrameDidNotSwap( |
| 1878 const cc::BeginFrameAck& ack) { | 1915 const cc::BeginFrameAck& ack) { |
| 1879 if (ack.sequence_number < cc::BeginFrameArgs::kStartingFrameNumber) { | 1916 if (ack.sequence_number < cc::BeginFrameArgs::kStartingFrameNumber) { |
| 1880 // Received an invalid ack, renderer misbehaved. | 1917 // Received an invalid ack, renderer misbehaved. |
| 1881 bad_message::ReceivedBadMessage( | 1918 bad_message::ReceivedBadMessage( |
| 1882 GetProcess(), bad_message::RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP); | 1919 GetProcess(), bad_message::RWH_INVALID_BEGIN_FRAME_ACK_DID_NOT_SWAP); |
| 1883 return; | 1920 return; |
| (...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2602 (frame_size != last_frame_size_ || | 2639 (frame_size != last_frame_size_ || |
| 2603 device_scale_factor != last_device_scale_factor_)) { | 2640 device_scale_factor != last_device_scale_factor_)) { |
| 2604 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." | 2641 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." |
| 2605 << " Expected: size=" << last_frame_size_.ToString() | 2642 << " Expected: size=" << last_frame_size_.ToString() |
| 2606 << ",scale=" << last_device_scale_factor_ | 2643 << ",scale=" << last_device_scale_factor_ |
| 2607 << " Received: size=" << frame_size.ToString() | 2644 << " Received: size=" << frame_size.ToString() |
| 2608 << ",scale=" << device_scale_factor; | 2645 << ",scale=" << device_scale_factor; |
| 2609 return; | 2646 return; |
| 2610 } | 2647 } |
| 2611 | 2648 |
| 2649 uint32_t frame_token = frame.metadata.frame_token; | |
| 2650 | |
| 2612 last_local_surface_id_ = local_surface_id; | 2651 last_local_surface_id_ = local_surface_id; |
| 2613 last_frame_size_ = frame_size; | 2652 last_frame_size_ = frame_size; |
| 2614 last_device_scale_factor_ = device_scale_factor; | 2653 last_device_scale_factor_ = device_scale_factor; |
| 2615 | 2654 |
| 2616 last_received_content_source_id_ = frame.metadata.content_source_id; | 2655 last_received_content_source_id_ = frame.metadata.content_source_id; |
| 2617 | 2656 |
| 2618 if (frame.metadata.begin_frame_ack.sequence_number < | 2657 if (frame.metadata.begin_frame_ack.sequence_number < |
| 2619 cc::BeginFrameArgs::kStartingFrameNumber) { | 2658 cc::BeginFrameArgs::kStartingFrameNumber) { |
| 2620 // Received an invalid ack, renderer misbehaved. | 2659 // Received an invalid ack, renderer misbehaved. |
| 2621 bad_message::ReceivedBadMessage( | 2660 bad_message::ReceivedBadMessage( |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 2652 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); | 2691 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
| 2653 SendReclaimCompositorResources(true /* is_swap_ack */, resources); | 2692 SendReclaimCompositorResources(true /* is_swap_ack */, resources); |
| 2654 } | 2693 } |
| 2655 | 2694 |
| 2656 // After navigation, if a frame belonging to the new page is received, stop | 2695 // After navigation, if a frame belonging to the new page is received, stop |
| 2657 // the timer that triggers clearing the graphics of the last page. | 2696 // the timer that triggers clearing the graphics of the last page. |
| 2658 if (last_received_content_source_id_ >= current_content_source_id_ && | 2697 if (last_received_content_source_id_ >= current_content_source_id_ && |
| 2659 new_content_rendering_timeout_->IsRunning()) { | 2698 new_content_rendering_timeout_->IsRunning()) { |
| 2660 new_content_rendering_timeout_->Stop(); | 2699 new_content_rendering_timeout_->Stop(); |
| 2661 } | 2700 } |
| 2701 | |
| 2702 if (frame_token) | |
| 2703 DidProcessFrame(frame_token); | |
| 2704 } | |
| 2705 | |
| 2706 void RenderWidgetHostImpl::DidProcessFrame(uint32_t frame_token) { | |
| 2707 // Frame tokens always increase. | |
| 2708 if (queued_tokens_.size() && frame_token <= queued_tokens_.back()) { | |
| 2709 bad_message::ReceivedBadMessage(GetProcess(), | |
| 2710 bad_message::RWH_INVALID_FRAME_TOKEN); | |
| 2711 return; | |
| 2712 } | |
| 2713 | |
| 2714 // We won't receive frames with tokens smaller than |frame_token| in the | |
| 2715 // future. Get rid of all messages queued for such frames. | |
| 2716 while (queued_messages_.size() && | |
| 2717 queued_messages_.front().first < frame_token) | |
| 2718 queued_messages_.pop_front(); | |
| 2719 | |
| 2720 // If there are no queued messages, add |frame_token| to |queued_tokens_| so | |
| 2721 // that we can process its messages once they arrive. | |
| 2722 if (queued_messages_.empty()) { | |
| 2723 queued_tokens_.push_back(frame_token); | |
| 2724 return; | |
| 2725 } | |
| 2726 | |
| 2727 // If the first element of |queued_messages_| belongs to |frame_token|, | |
| 2728 // process the queued messages. | |
| 2729 if (queued_messages_.front().first == frame_token) { | |
| 2730 ProcessSwapMessages(std::move(queued_messages_.front().second)); | |
| 2731 queued_messages_.pop_front(); | |
| 2732 return; | |
| 2733 } | |
| 2734 | |
| 2735 // The first element of |queued_messages_| belongs to a larger frame token. | |
| 2736 // This should not happen. The renderer is misbehaving. | |
| 2737 bad_message::ReceivedBadMessage(GetProcess(), | |
| 2738 bad_message::RWH_INVALID_FRAME_TOKEN); | |
| 2739 } | |
| 2740 | |
| 2741 void RenderWidgetHostImpl::ProcessSwapMessages( | |
| 2742 std::vector<IPC::Message> messages) { | |
| 2743 RenderProcessHost* rph = GetProcess(); | |
| 2744 for (std::vector<IPC::Message>::const_iterator i = messages.begin(); | |
| 2745 i != messages.end(); ++i) { | |
| 2746 rph->OnMessageReceived(*i); | |
| 2747 if (i->dispatch_error()) | |
| 2748 rph->OnBadMessageReceived(*i); | |
| 2749 } | |
| 2662 } | 2750 } |
| 2663 | 2751 |
| 2664 } // namespace content | 2752 } // namespace content |
| OLD | NEW |