Index: content/browser/renderer_host/render_widget_host_impl.cc |
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc |
index 45aa1a69b468658390a50e3569a002ad0896db34..dae907f5c8c0bea34f716b26b53438e56f9d8362 100644 |
--- a/content/browser/renderer_host/render_widget_host_impl.cc |
+++ b/content/browser/renderer_host/render_widget_host_impl.cc |
@@ -1843,80 +1843,13 @@ bool RenderWidgetHostImpl::OnSwapCompositorFrame( |
std::vector<IPC::Message> messages_to_deliver_with_frame; |
messages_to_deliver_with_frame.swap(std::get<3>(param)); |
- // The renderer should not send empty frames. |
- if (frame.render_pass_list.empty()) { |
- DLOG(ERROR) << "Renderer sent an empty frame."; |
- return false; |
- } |
- |
- // The renderer must allocate a new LocalSurfaceId if frame size or device |
- // scale factor changes. |
- float device_scale_factor = frame.metadata.device_scale_factor; |
- const gfx::Size& frame_size = |
- frame.render_pass_list.back()->output_rect.size(); |
- if (local_surface_id == last_local_surface_id_ && |
- (frame_size != last_frame_size_ || |
- device_scale_factor != last_device_scale_factor_)) { |
- DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." |
- << " Expected: size=" << last_frame_size_.ToString() |
- << ",scale=" << last_device_scale_factor_ |
- << " Received: size=" << frame_size.ToString() |
- << ",scale=" << device_scale_factor; |
- return false; |
+ if (compositor_frame_sink_id != last_compositor_frame_sink_id_) { |
+ if (view_) |
+ view_->DidCreateNewRendererCompositorFrameSink(); |
+ last_compositor_frame_sink_id_ = compositor_frame_sink_id; |
} |
- last_local_surface_id_ = local_surface_id; |
- last_frame_size_ = frame_size; |
- last_device_scale_factor_ = device_scale_factor; |
- last_received_content_source_id_ = frame.metadata.content_source_id; |
- |
- if (frame.metadata.begin_frame_ack.sequence_number < |
- cc::BeginFrameArgs::kStartingFrameNumber) { |
- // Received an invalid ack, renderer misbehaved. |
- bad_message::ReceivedBadMessage( |
- GetProcess(), |
- bad_message::RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME); |
- return false; |
- } |
- // |has_damage| is not transmitted. |
- frame.metadata.begin_frame_ack.has_damage = true; |
- |
- if (!ui::LatencyInfo::Verify(frame.metadata.latency_info, |
- "RenderWidgetHostImpl::OnSwapCompositorFrame")) { |
- std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info); |
- } |
- |
- latency_tracker_.OnSwapCompositorFrame(&frame.metadata.latency_info); |
- |
- bool is_mobile_optimized = IsMobileOptimizedFrame(frame.metadata); |
- input_router_->NotifySiteIsMobileOptimized(is_mobile_optimized); |
- if (touch_emulator_) |
- touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized); |
- |
- // Ignore this frame if its content has already been unloaded. Source ID |
- // is always zero for an OOPIF because we are only concerned with displaying |
- // stale graphics on top-level frames. We accept frames that have a source ID |
- // greater than |current_content_source_id_| because in some cases the first |
- // compositor frame can arrive before the navigation commit message that |
- // updates that value. |
- if (view_ && frame.metadata.content_source_id >= current_content_source_id_) { |
- view_->OnSwapCompositorFrame(compositor_frame_sink_id, local_surface_id, |
- std::move(frame)); |
- view_->DidReceiveRendererFrame(); |
- } else { |
- cc::ReturnedResourceArray resources; |
- cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
- SendReclaimCompositorResources(routing_id_, compositor_frame_sink_id, |
- process_->GetID(), true /* is_swap_ack */, |
- resources); |
- } |
- |
- // After navigation, if a frame belonging to the new page is received, stop |
- // the timer that triggers clearing the graphics of the last page. |
- if (last_received_content_source_id_ >= current_content_source_id_ && |
- new_content_rendering_timeout_->IsRunning()) { |
- new_content_rendering_timeout_->Stop(); |
- } |
+ SubmitCompositorFrame(local_surface_id, std::move(frame)); |
RenderProcessHost* rph = GetProcess(); |
for (std::vector<IPC::Message>::const_iterator i = |
@@ -2375,18 +2308,11 @@ bool RenderWidgetHostImpl::GotResponseToLockMouseRequest(bool allowed) { |
return true; |
} |
-// static |
void RenderWidgetHostImpl::SendReclaimCompositorResources( |
- int32_t route_id, |
- uint32_t compositor_frame_sink_id, |
- int renderer_host_id, |
bool is_swap_ack, |
const cc::ReturnedResourceArray& resources) { |
- RenderProcessHost* host = RenderProcessHost::FromID(renderer_host_id); |
- if (!host) |
- return; |
- host->Send(new ViewMsg_ReclaimCompositorResources( |
- route_id, compositor_frame_sink_id, is_swap_ack, resources)); |
+ Send(new ViewMsg_ReclaimCompositorResources( |
+ routing_id_, last_compositor_frame_sink_id_, is_swap_ack, resources)); |
} |
void RenderWidgetHostImpl::DelayedAutoResized() { |
@@ -2654,4 +2580,81 @@ void RenderWidgetHostImpl::RequestCompositionUpdates(bool immediate_request, |
monitor_updates)); |
} |
+void RenderWidgetHostImpl::SubmitCompositorFrame( |
+ const cc::LocalSurfaceId& local_surface_id, |
+ cc::CompositorFrame frame) { |
+ // The renderer should not send empty frames. |
+ if (frame.render_pass_list.empty()) { |
+ DLOG(ERROR) << "Renderer sent an empty frame."; |
+ return; |
+ } |
+ |
+ // The renderer must allocate a new LocalSurfaceId if frame size or device |
+ // scale factor changes. |
+ float device_scale_factor = frame.metadata.device_scale_factor; |
+ const gfx::Size& frame_size = |
+ frame.render_pass_list.back()->output_rect.size(); |
+ if (local_surface_id == last_local_surface_id_ && |
+ (frame_size != last_frame_size_ || |
+ device_scale_factor != last_device_scale_factor_)) { |
+ DLOG(ERROR) << "Renderer submitted frame of wrong size to its surface." |
+ << " Expected: size=" << last_frame_size_.ToString() |
+ << ",scale=" << last_device_scale_factor_ |
+ << " Received: size=" << frame_size.ToString() |
+ << ",scale=" << device_scale_factor; |
+ return; |
+ } |
+ |
+ last_local_surface_id_ = local_surface_id; |
+ last_frame_size_ = frame_size; |
+ last_device_scale_factor_ = device_scale_factor; |
+ |
+ last_received_content_source_id_ = frame.metadata.content_source_id; |
+ |
+ if (frame.metadata.begin_frame_ack.sequence_number < |
+ cc::BeginFrameArgs::kStartingFrameNumber) { |
+ // Received an invalid ack, renderer misbehaved. |
+ bad_message::ReceivedBadMessage( |
+ GetProcess(), |
+ bad_message::RWH_INVALID_BEGIN_FRAME_ACK_COMPOSITOR_FRAME); |
+ return; |
+ } |
+ // |has_damage| is not transmitted. |
+ frame.metadata.begin_frame_ack.has_damage = true; |
+ |
+ if (!ui::LatencyInfo::Verify(frame.metadata.latency_info, |
+ "RenderWidgetHostImpl::OnSwapCompositorFrame")) { |
+ std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info); |
+ } |
+ |
+ latency_tracker_.OnSwapCompositorFrame(&frame.metadata.latency_info); |
+ |
+ bool is_mobile_optimized = IsMobileOptimizedFrame(frame.metadata); |
+ input_router_->NotifySiteIsMobileOptimized(is_mobile_optimized); |
+ if (touch_emulator_) |
+ touch_emulator_->SetDoubleTapSupportForPageEnabled(!is_mobile_optimized); |
+ |
+ // Ignore this frame if its content has already been unloaded. Source ID |
+ // is always zero for an OOPIF because we are only concerned with displaying |
+ // stale graphics on top-level frames. We accept frames that have a source ID |
+ // greater than |current_content_source_id_| because in some cases the first |
+ // compositor frame can arrive before the navigation commit message that |
+ // updates that value. |
+ if (view_ && frame.metadata.content_source_id >= current_content_source_id_) { |
+ view_->SubmitCompositorFrame(local_surface_id, std::move(frame)); |
+ view_->DidReceiveRendererFrame(); |
+ } else { |
+ cc::ReturnedResourceArray resources; |
+ cc::TransferableResource::ReturnResources(frame.resource_list, &resources); |
+ SendReclaimCompositorResources(true /* is_swap_ack */, resources); |
+ } |
+ |
+ // After navigation, if a frame belonging to the new page is received, stop |
+ // the timer that triggers clearing the graphics of the last page. |
+ if (last_received_content_source_id_ >= current_content_source_id_ && |
+ new_content_rendering_timeout_->IsRunning()) { |
+ new_content_rendering_timeout_->Stop(); |
+ } |
+} |
+ |
} // namespace content |