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 15b899540dc237e86f109eb9d4e65a42d230ea75..40792db0592e97a2291abe8b9dda8c23777a4fe0 100644 |
| --- a/content/browser/renderer_host/render_widget_host_impl.cc |
| +++ b/content/browser/renderer_host/render_widget_host_impl.cc |
| @@ -91,6 +91,7 @@ |
| #include "ui/gfx/image/image.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/skbitmap_operations.h" |
| +#include "ui/gfx/switches.h" |
| #include "ui/snapshot/snapshot.h" |
| #if defined(OS_ANDROID) |
| @@ -1450,6 +1451,17 @@ void RenderWidgetHostImpl::GetSnapshotFromBrowser( |
| Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info)); |
| } |
| +void RenderWidgetHostImpl::GetBitmapSnapshotFromBrowser( |
| + const GetBitmapSnapshotFromBrowserCallback& callback) { |
| + int id = next_browser_snapshot_id_++; |
| + |
| + pending_bitmap_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(); |
| @@ -2351,6 +2363,16 @@ void RenderWidgetHostImpl::DidReceiveRendererFrame() { |
| void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) { |
| DCHECK(base::MessageLoopForUI::IsCurrent()); |
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless)) { |
|
Eric Seckler
2017/03/06 07:32:53
If we use the headless switch to determine how we
dgozman
2017/03/06 18:45:34
We should not special-case headless here.
dvallet
2017/03/08 02:26:14
Done.
dvallet
2017/03/08 02:26:14
Done. I opted to check both.
|
| + // In headless mode, we capture the whole view. |
| + GetView()->CopyFromSurface( |
| + gfx::Rect(), gfx::Size(), |
| + base::Bind(&RenderWidgetHostImpl::OnBitmapSnapshotReceived, |
| + weak_factory_.GetWeakPtr(), snapshot_id, 0), |
| + kN32_SkColorType); |
| + return; |
| + } |
| + |
| #if defined(OS_ANDROID) |
| // On Android, call sites should pass in the bounds with correct offset |
| // to capture the intended content area. |
| @@ -2373,6 +2395,33 @@ void RenderWidgetHostImpl::WindowSnapshotReachedScreen(int snapshot_id) { |
| weak_factory_.GetWeakPtr(), snapshot_id)); |
| } |
| +void RenderWidgetHostImpl::OnBitmapSnapshotReceived(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::OnBitmapSnapshotReceived, |
| + 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. |
| + PendingBitmapSnapshotMap::iterator it = |
| + pending_bitmap_browser_snapshots_.begin(); |
| + while (it != pending_bitmap_browser_snapshots_.end()) { |
| + if (it->first <= snapshot_id) { |
| + it->second.Run(bitmap); |
| + pending_bitmap_browser_snapshots_.erase(it++); |
| + } else { |
| + ++it; |
| + } |
| + } |
| +} |
| + |
| void RenderWidgetHostImpl::OnSnapshotReceived(int snapshot_id, |
| const gfx::Image& image) { |
| // Any pending snapshots with a lower ID than the one received are considered |