Chromium Code Reviews| 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 eaff97c650cd7b6a5ac8cc2847d53f9386a07b74..cd088cbac5b86f8ab1fe49073f6a58e734a7c20e 100644 |
| --- a/content/browser/renderer_host/render_widget_host_impl.cc |
| +++ b/content/browser/renderer_host/render_widget_host_impl.cc |
| @@ -1455,6 +1455,17 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( |
| Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info)); |
| } |
| +void RenderWidgetHostImpl::GetSurfaceSnapshotFromBrowser( |
| + const GetSnapshotFromBrowserCallback& callback) { |
| + int id = next_browser_snapshot_id_++; |
| + |
| + pending_surface_browser_snapshots_.insert(std::make_pair(id, callback)); |
| + ui::LatencyInfo latency_info; |
| + latency_info.AddLatencyNumber(ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT, 0, |
| + id); |
| + Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info)); |
| +} |
| + |
| const NativeWebKeyboardEvent* |
| RenderWidgetHostImpl::GetLastKeyboardEvent() const { |
| return input_router_->GetLastKeyboardEvent(); |
| @@ -2362,26 +2373,64 @@ void RenderWidgetHostImpl::DidReceiveRendererFrame() { |
| void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) { |
| DCHECK(base::MessageLoopForUI::IsCurrent()); |
| + if (!pending_surface_browser_snapshots_.empty()) { |
| + GetView()->CopyFromSurface( |
| + gfx::Rect(), gfx::Size(), |
| + base::Bind(&RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived, |
| + weak_factory_.GetWeakPtr(), snapshot_id, 0), |
| + kN32_SkColorType); |
| + } |
| + |
| + if (!pending_browser_snapshots_.empty()) { |
| #if defined(OS_ANDROID) |
| - // On Android, call sites should pass in the bounds with correct offset |
| - // to capture the intended content area. |
| - gfx::Rect snapshot_bounds(GetView()->GetViewBounds()); |
| - snapshot_bounds.Offset(0, GetView()->GetNativeView()->content_offset().y()); |
| + // On Android, call sites should pass in the bounds with correct offset |
| + // to capture the intended content area. |
| + gfx::Rect snapshot_bounds(GetView()->GetViewBounds()); |
| + snapshot_bounds.Offset(0, GetView()->GetNativeView()->content_offset().y()); |
| #else |
| - gfx::Rect snapshot_bounds(GetView()->GetViewBounds().size()); |
| + gfx::Rect snapshot_bounds(GetView()->GetViewBounds().size()); |
| #endif |
| - gfx::Image image; |
| - if (ui::GrabViewSnapshot(GetView()->GetNativeView(), snapshot_bounds, |
| - &image)) { |
| - OnSnapshotReceived(snapshot_id, image); |
| - return; |
| + gfx::Image image; |
| + if (ui::GrabViewSnapshot(GetView()->GetNativeView(), snapshot_bounds, |
| + &image)) { |
| + OnSnapshotReceived(snapshot_id, image); |
| + return; |
| + } |
| + |
| + ui::GrabViewSnapshotAsync( |
| + GetView()->GetNativeView(), snapshot_bounds, |
| + base::Bind(&RenderWidgetHostImpl::OnSnapshotReceived, |
| + weak_factory_.GetWeakPtr(), snapshot_id)); |
| } |
| +} |
| - ui::GrabViewSnapshotAsync( |
| - GetView()->GetNativeView(), snapshot_bounds, |
| - base::Bind(&RenderWidgetHostImpl::OnSnapshotReceived, |
| - weak_factory_.GetWeakPtr(), snapshot_id)); |
| +void RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived( |
| + int snapshot_id, |
| + int retry_count, |
| + const SkBitmap& bitmap, |
| + ReadbackResponse response) { |
| + static const int kMaxRetries = 5; |
| + if (response != READBACK_SUCCESS && retry_count < kMaxRetries) { |
| + GetView()->CopyFromSurface( |
| + gfx::Rect(), gfx::Size(), |
| + base::Bind(&RenderWidgetHostImpl::OnSnapshotFromSurfaceReceived, |
| + weak_factory_.GetWeakPtr(), snapshot_id, retry_count + 1), |
| + kN32_SkColorType); |
| + return; |
| + } |
| + // Any pending snapshots with a lower ID than the one received are considered |
| + // to be implicitly complete, and returned the same snapshot data. |
| + PendingSnapshotFromSurfaceMap::iterator it = |
| + pending_surface_browser_snapshots_.begin(); |
| + while (it != pending_surface_browser_snapshots_.end()) { |
| + if (it->first <= snapshot_id) { |
| + it->second.Run(gfx::Image::CreateFrom1xBitmap(bitmap)); |
|
Eric Seckler
2017/03/09 09:55:22
nit: create gfx::Image outside the loop.
Maybe al
dvallet
2017/03/09 22:43:52
Done on outside loop image creation.
Regarding emp
dvallet
2017/03/10 00:07:27
I see that GetSnapshotFromBrowser does indicate th
|
| + pending_surface_browser_snapshots_.erase(it++); |
| + } else { |
| + ++it; |
| + } |
| + } |
| } |
| void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id, |