| 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 1825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1836 | 1836 |
| 1837 ViewHostMsg_SwapCompositorFrame::Param param; | 1837 ViewHostMsg_SwapCompositorFrame::Param param; |
| 1838 if (!ViewHostMsg_SwapCompositorFrame::Read(&message, ¶m)) | 1838 if (!ViewHostMsg_SwapCompositorFrame::Read(&message, ¶m)) |
| 1839 return false; | 1839 return false; |
| 1840 uint32_t compositor_frame_sink_id = std::get<0>(param); | 1840 uint32_t compositor_frame_sink_id = std::get<0>(param); |
| 1841 cc::LocalSurfaceId local_surface_id = std::get<1>(param); | 1841 cc::LocalSurfaceId local_surface_id = std::get<1>(param); |
| 1842 cc::CompositorFrame frame(std::move(std::get<2>(param))); | 1842 cc::CompositorFrame frame(std::move(std::get<2>(param))); |
| 1843 std::vector<IPC::Message> messages_to_deliver_with_frame; | 1843 std::vector<IPC::Message> messages_to_deliver_with_frame; |
| 1844 messages_to_deliver_with_frame.swap(std::get<3>(param)); | 1844 messages_to_deliver_with_frame.swap(std::get<3>(param)); |
| 1845 | 1845 |
| 1846 // The renderer should not send empty frames. | 1846 if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
| 1847 if (frame.render_pass_list.empty()) { | 1847 if (view_) |
| 1848 DLOG(ERROR) << "Renderer sent an empty frame."; | 1848 view_->DidCreateNewRendererCompositorFrameSink(); |
| 1849 return false; | 1849 last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
| 1850 } | 1850 } |
| 1851 | 1851 |
| 1852 // The renderer must allocate a new LocalSurfaceId if frame size or device | 1852 SubmitCompositorFrame(local_surface_id, std::move(frame)); |
| 1853 // scale factor changes. | |
| 1854 float device_scale_factor = frame.metadata.device_scale_factor; | |
| 1855 const gfx::Size& frame_size = | |
| 1856 frame.render_pass_list.back()->output_rect.size(); | |
| 1857 if (local_surface_id == last_local_surface_id_ && | |
| 1858 (frame_size != last_frame_size_ || | |
| 1859 device_scale_factor != last_device_scale_factor_)) { | |
| 1860 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." | |
| 1861 << " Expected: size=" << last_frame_size_.ToString() | |
| 1862 << ",scale=" << last_device_scale_factor_ | |
| 1863 << " Received: size=" << frame_size.ToString() | |
| 1864 << ",scale=" << device_scale_factor; | |
| 1865 return false; | |
| 1866 } | |
| 1867 last_local_surface_id_ = local_surface_id; | |
| 1868 last_frame_size_ = frame_size; | |
| 1869 last_device_scale_factor_ = device_scale_factor; | |
| 1870 | |
| 1871 last_received_content_source_id_ = frame.metadata.content_source_id; | |
| 1872 | |
| 1873 if (frame.metadata.begin_frame_ack.sequence_number < | |
| 1874 cc::BeginFrameArgs::kStartingFrameNumber) { | |
| 1875 // Received an invalid ack, renderer misbehaved. | |
| 1876 bad_message::ReceivedBadMessage( | |
| 1877 GetProcess(), | |
| 1878 bad_message::RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME); | |
| 1879 return false; | |
| 1880 } | |
| 1881 // |has_damage| is not transmitted. | |
| 1882 frame.metadata.begin_frame_ack.has_damage = true; | |
| 1883 | |
| 1884 if (!ui::LatencyInfo::Verify(frame.metadata.latency_info, | |
| 1885 "RenderWidgetHostImpl::OnSwapCompositorFrame")) { | |
| 1886 std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info); | |
| 1887 } | |
| 1888 | |
| 1889 latency_tracker_.OnSwapCompositorFrame(&frame.metadata.latency_info); | |
| 1890 | |
| 1891 bool is_mobile_optimized = IsMobileOptimizedFrame(frame.metadata); | |
| 1892 input_router_->NotifySiteIsMobileOptimized(is_mobile_optimized); | |
| 1893 if (touch_emulator_) | |
| 1894 touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized); | |
| 1895 | |
| 1896 // Ignore this frame if its content has already been unloaded. Source ID | |
| 1897 // is always zero for an OOPIF because we are only concerned with displaying | |
| 1898 // stale graphics on top-level frames. We accept frames that have a source ID | |
| 1899 // greater than |current_content_source_id_| because in some cases the first | |
| 1900 // compositor frame can arrive before the navigation commit message that | |
| 1901 // updates that value. | |
| 1902 if (view_ && frame.metadata.content_source_id >= current_content_source_id_) { | |
| 1903 view_->OnSwapCompositorFrame(compositor_frame_sink_id, local_surface_id, | |
| 1904 std::move(frame)); | |
| 1905 view_->DidReceiveRendererFrame(); | |
| 1906 } else { | |
| 1907 cc::ReturnedResourceArray resources; | |
| 1908 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); | |
| 1909 SendReclaimCompositorResources(routing_id_, compositor_frame_sink_id, | |
| 1910 process_->GetID(), true /* is_swap_ack */, | |
| 1911 resources); | |
| 1912 } | |
| 1913 | |
| 1914 // After navigation, if a frame belonging to the new page is received, stop | |
| 1915 // the timer that triggers clearing the graphics of the last page. | |
| 1916 if (last_received_content_source_id_ >= current_content_source_id_ && | |
| 1917 new_content_rendering_timeout_->IsRunning()) { | |
| 1918 new_content_rendering_timeout_->Stop(); | |
| 1919 } | |
| 1920 | 1853 |
| 1921 RenderProcessHost* rph = GetProcess(); | 1854 RenderProcessHost* rph = GetProcess(); |
| 1922 for (std::vector<IPC::Message>::const_iterator i = | 1855 for (std::vector<IPC::Message>::const_iterator i = |
| 1923 messages_to_deliver_with_frame.begin(); | 1856 messages_to_deliver_with_frame.begin(); |
| 1924 i != messages_to_deliver_with_frame.end(); | 1857 i != messages_to_deliver_with_frame.end(); |
| 1925 ++i) { | 1858 ++i) { |
| 1926 rph->OnMessageReceived(*i); | 1859 rph->OnMessageReceived(*i); |
| 1927 if (i->dispatch_error()) | 1860 if (i->dispatch_error()) |
| 1928 rph->OnBadMessageReceived(*i); | 1861 rph->OnBadMessageReceived(*i); |
| 1929 } | 1862 } |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2368 pending_mouse_lock_request_ = false; | 2301 pending_mouse_lock_request_ = false; |
| 2369 if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) { | 2302 if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) { |
| 2370 Send(new ViewMsg_LockMouse_ACK(routing_id_, false)); | 2303 Send(new ViewMsg_LockMouse_ACK(routing_id_, false)); |
| 2371 return false; | 2304 return false; |
| 2372 } | 2305 } |
| 2373 | 2306 |
| 2374 Send(new ViewMsg_LockMouse_ACK(routing_id_, true)); | 2307 Send(new ViewMsg_LockMouse_ACK(routing_id_, true)); |
| 2375 return true; | 2308 return true; |
| 2376 } | 2309 } |
| 2377 | 2310 |
| 2378 // static | |
| 2379 void RenderWidgetHostImpl::SendReclaimCompositorResources( | 2311 void RenderWidgetHostImpl::SendReclaimCompositorResources( |
| 2380 int32_t route_id, | |
| 2381 uint32_t compositor_frame_sink_id, | |
| 2382 int renderer_host_id, | |
| 2383 bool is_swap_ack, | 2312 bool is_swap_ack, |
| 2384 const cc::ReturnedResourceArray& resources) { | 2313 const cc::ReturnedResourceArray& resources) { |
| 2385 RenderProcessHost* host = RenderProcessHost::FromID(renderer_host_id); | 2314 Send(new ViewMsg_ReclaimCompositorResources( |
| 2386 if (!host) | 2315 routing_id_, last_compositor_frame_sink_id_, is_swap_ack, resources)); |
| 2387 return; | |
| 2388 host->Send(new ViewMsg_ReclaimCompositorResources( | |
| 2389 route_id, compositor_frame_sink_id, is_swap_ack, resources)); | |
| 2390 } | 2316 } |
| 2391 | 2317 |
| 2392 void RenderWidgetHostImpl::DelayedAutoResized() { | 2318 void RenderWidgetHostImpl::DelayedAutoResized() { |
| 2393 gfx::Size new_size = new_auto_size_; | 2319 gfx::Size new_size = new_auto_size_; |
| 2394 // Clear the new_auto_size_ since the empty value is used as a flag to | 2320 // Clear the new_auto_size_ since the empty value is used as a flag to |
| 2395 // indicate that no callback is in progress (i.e. without this line | 2321 // indicate that no callback is in progress (i.e. without this line |
| 2396 // DelayedAutoResized will not get called again). | 2322 // DelayedAutoResized will not get called again). |
| 2397 new_auto_size_.SetSize(0, 0); | 2323 new_auto_size_.SetSize(0, 0); |
| 2398 if (!auto_resize_enabled_) | 2324 if (!auto_resize_enabled_) |
| 2399 return; | 2325 return; |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2647 | 2573 |
| 2648 void RenderWidgetHostImpl::RequestCompositionUpdates(bool immediate_request, | 2574 void RenderWidgetHostImpl::RequestCompositionUpdates(bool immediate_request, |
| 2649 bool monitor_updates) { | 2575 bool monitor_updates) { |
| 2650 if (!immediate_request && monitor_updates == monitoring_composition_info_) | 2576 if (!immediate_request && monitor_updates == monitoring_composition_info_) |
| 2651 return; | 2577 return; |
| 2652 monitoring_composition_info_ = monitor_updates; | 2578 monitoring_composition_info_ = monitor_updates; |
| 2653 Send(new InputMsg_RequestCompositionUpdates(routing_id_, immediate_request, | 2579 Send(new InputMsg_RequestCompositionUpdates(routing_id_, immediate_request, |
| 2654 monitor_updates)); | 2580 monitor_updates)); |
| 2655 } | 2581 } |
| 2656 | 2582 |
| 2583 void RenderWidgetHostImpl::SubmitCompositorFrame( |
| 2584 const cc::LocalSurfaceId& local_surface_id, |
| 2585 cc::CompositorFrame frame) { |
| 2586 // The renderer should not send empty frames. |
| 2587 if (frame.render_pass_list.empty()) { |
| 2588 DLOG(ERROR) << "Renderer sent an empty frame."; |
| 2589 return; |
| 2590 } |
| 2591 |
| 2592 // The renderer must allocate a new LocalSurfaceId if frame size or device |
| 2593 // scale factor changes. |
| 2594 float device_scale_factor = frame.metadata.device_scale_factor; |
| 2595 const gfx::Size& frame_size = |
| 2596 frame.render_pass_list.back()->output_rect.size(); |
| 2597 if (local_surface_id == last_local_surface_id_ && |
| 2598 (frame_size != last_frame_size_ || |
| 2599 device_scale_factor != last_device_scale_factor_)) { |
| 2600 DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." |
| 2601 << " Expected: size=" << last_frame_size_.ToString() |
| 2602 << ",scale=" << last_device_scale_factor_ |
| 2603 << " Received: size=" << frame_size.ToString() |
| 2604 << ",scale=" << device_scale_factor; |
| 2605 return; |
| 2606 } |
| 2607 |
| 2608 last_local_surface_id_ = local_surface_id; |
| 2609 last_frame_size_ = frame_size; |
| 2610 last_device_scale_factor_ = device_scale_factor; |
| 2611 |
| 2612 last_received_content_source_id_ = frame.metadata.content_source_id; |
| 2613 |
| 2614 if (frame.metadata.begin_frame_ack.sequence_number < |
| 2615 cc::BeginFrameArgs::kStartingFrameNumber) { |
| 2616 // Received an invalid ack, renderer misbehaved. |
| 2617 bad_message::ReceivedBadMessage( |
| 2618 GetProcess(), |
| 2619 bad_message::RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME); |
| 2620 return; |
| 2621 } |
| 2622 // |has_damage| is not transmitted. |
| 2623 frame.metadata.begin_frame_ack.has_damage = true; |
| 2624 |
| 2625 if (!ui::LatencyInfo::Verify(frame.metadata.latency_info, |
| 2626 "RenderWidgetHostImpl::OnSwapCompositorFrame")) { |
| 2627 std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info); |
| 2628 } |
| 2629 |
| 2630 latency_tracker_.OnSwapCompositorFrame(&frame.metadata.latency_info); |
| 2631 |
| 2632 bool is_mobile_optimized = IsMobileOptimizedFrame(frame.metadata); |
| 2633 input_router_->NotifySiteIsMobileOptimized(is_mobile_optimized); |
| 2634 if (touch_emulator_) |
| 2635 touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized); |
| 2636 |
| 2637 // Ignore this frame if its content has already been unloaded. Source ID |
| 2638 // is always zero for an OOPIF because we are only concerned with displaying |
| 2639 // stale graphics on top-level frames. We accept frames that have a source ID |
| 2640 // greater than |current_content_source_id_| because in some cases the first |
| 2641 // compositor frame can arrive before the navigation commit message that |
| 2642 // updates that value. |
| 2643 if (view_ && frame.metadata.content_source_id >= current_content_source_id_) { |
| 2644 view_->SubmitCompositorFrame(local_surface_id, std::move(frame)); |
| 2645 view_->DidReceiveRendererFrame(); |
| 2646 } else { |
| 2647 cc::ReturnedResourceArray resources; |
| 2648 cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
| 2649 SendReclaimCompositorResources(true /* is_swap_ack */, resources); |
| 2650 } |
| 2651 |
| 2652 // After navigation, if a frame belonging to the new page is received, stop |
| 2653 // the timer that triggers clearing the graphics of the last page. |
| 2654 if (last_received_content_source_id_ >= current_content_source_id_ && |
| 2655 new_content_rendering_timeout_->IsRunning()) { |
| 2656 new_content_rendering_timeout_->Stop(); |
| 2657 } |
| 2658 } |
| 2659 |
| 2657 } // namespace content | 2660 } // namespace content |
| OLD | NEW |