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 4afec65e2be43a227764516076b2ccd59f26758f..1220debf55e5f809070081f35606095cce576501 100644 |
| --- a/content/browser/renderer_host/render_widget_host_impl.cc |
| +++ b/content/browser/renderer_host/render_widget_host_impl.cc |
| @@ -1453,6 +1453,17 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( |
| Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info)); |
| } |
| +void RenderWidgetHostImpl::GetSurfaceSnapshotFromBrowser( |
| + const GetSurfaceSnapshotFromBrowserCallback& 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(); |
| @@ -2360,26 +2371,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; |
|
dgozman
2017/03/08 19:21:36
Why do we need retries?
dvallet
2017/03/09 06:19:47
I copied this code from Eric's patch https://coder
Eric Seckler
2017/03/09 09:55:22
Yup, and it also mimics
https://cs.chromium.org/ch
|
| + 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(bitmap); |
| + pending_surface_browser_snapshots_.erase(it++); |
| + } else { |
| + ++it; |
| + } |
| + } |
| } |
| void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id, |