Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: content/browser/renderer_host/render_widget_host_impl.cc

Issue 2789773003: Send FrameSwapMessageQueue's messages with a separate IPC (Closed)
Patch Set: c Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698