Chromium Code Reviews| Index: content/browser/renderer_host/render_widget_host_view_android.cc |
| diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc |
| index 19b64c6f5043fcfa27550f8a4529401dd24284a6..6f2ab093402e0a023aeca6382a740c0f0fa0b1d9 100644 |
| --- a/content/browser/renderer_host/render_widget_host_view_android.cc |
| +++ b/content/browser/renderer_host/render_widget_host_view_android.cc |
| @@ -170,6 +170,23 @@ bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) { |
| } // anonymous namespace |
| +ReadbackRequest::ReadbackRequest( |
| + float scale, |
| + SkColorType color_type, |
| + gfx::Rect src_subrect, |
| + const base::Callback<void(bool, const SkBitmap&)>& result_callback) |
| + : scale_(scale), |
| + color_type_(color_type), |
| + src_subrect_(src_subrect), |
| + result_callback_(result_callback) { |
| +} |
| + |
| +ReadbackRequest::ReadbackRequest() { |
| +} |
| + |
| +ReadbackRequest::~ReadbackRequest() { |
| +} |
| + |
| RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo( |
| uint32 output_id, |
| scoped_ptr<cc::CompositorFrame> output_frame) |
| @@ -212,6 +229,7 @@ RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { |
| ImageTransportFactoryAndroid::RemoveObserver(this); |
| SetContentViewCore(NULL); |
| DCHECK(ack_callbacks_.empty()); |
| + DCHECK(readbacks_waiting_for_frame_.empty()); |
| if (resource_collection_.get()) |
| resource_collection_->SetClient(NULL); |
| } |
| @@ -295,6 +313,14 @@ void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { |
| SetSize(rect.size()); |
| } |
| +void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() { |
| + while (!readbacks_waiting_for_frame_.empty()) { |
| + ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front(); |
| + readback_request.GetResultCallback().Run(false, SkBitmap()); |
| + readbacks_waiting_for_frame_.pop(); |
| + } |
| +} |
| + |
| void RenderWidgetHostViewAndroid::GetScaledContentBitmap( |
| float scale, |
| SkColorType color_type, |
| @@ -305,9 +331,11 @@ void RenderWidgetHostViewAndroid::GetScaledContentBitmap( |
| return; |
| } |
| if (!IsSurfaceAvailableForCopy()) { |
| - // TODO(Sikugu): allow a read-back request to wait for a first frame if it |
| - // was invoked while no frame was received yet |
| - result_callback.Run(false, SkBitmap()); |
| + // The view is visible, probably the frame has not yet arrived. |
| + // Just add the ReadbackRequest to queue and wait for frame arrival |
| + // to get this request processed. |
| + readbacks_waiting_for_frame_.push( |
| + ReadbackRequest(scale, color_type, src_subrect, result_callback)); |
| return; |
| } |
| @@ -334,7 +362,7 @@ bool RenderWidgetHostViewAndroid::HasValidFrame() const { |
| if (texture_size_in_layer_.IsEmpty()) |
| return false; |
| - |
| + // This tell us whether a valid frame has arrived or not. |
| if (!frame_evictor_->HasFrame()) |
| return false; |
| @@ -409,6 +437,9 @@ void RenderWidgetHostViewAndroid::Hide() { |
| layer_->SetHideLayerAndSubtree(true); |
| frame_evictor_->SetVisible(false); |
| + // We are hiding a renderer and any readback requests pending on frame arrival |
| + // need to be addressed here. |
|
no sievers
2014/08/19 17:47:07
nit: I'd say that we don't know if we will ever ge
sivag
2014/08/20 07:10:53
Done.
|
| + AbortPendingReadbackRequests(); |
| WasHidden(); |
| } |
| @@ -849,6 +880,9 @@ void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { |
| RemoveLayers(); |
| frame_provider_ = NULL; |
| layer_ = NULL; |
| + // This gets called when ever any eviction, loosing resources, swapping |
| + // problems are encountered and so we abort any pending readbacks here. |
| + AbortPendingReadbackRequests(); |
| } |
| void RenderWidgetHostViewAndroid::SwapDelegatedFrame( |
| @@ -965,6 +999,18 @@ void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame( |
| // As the metadata update may trigger view invalidation, always call it after |
| // any potential compositor scheduling. |
| OnFrameMetadataUpdated(frame->metadata); |
| + // Check if we have any pending readbacks, see if we have a frame available |
| + // and process them here. |
| + if (!readbacks_waiting_for_frame_.empty() && HasValidFrame()) { |
|
no sievers
2014/08/19 17:47:07
nit: Isn't HasValidFrame() always true at this loc
sivag
2014/08/20 07:10:53
Done.
|
| + while (!readbacks_waiting_for_frame_.empty()) { |
| + ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front(); |
| + GetScaledContentBitmap(readback_request.GetScale(), |
| + readback_request.GetColorFormat(), |
| + readback_request.GetCaptureRect(), |
| + readback_request.GetResultCallback()); |
| + readbacks_waiting_for_frame_.pop(); |
| + } |
| + } |
| } |
| void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( |
| @@ -1190,6 +1236,9 @@ void RenderWidgetHostViewAndroid::EvictDelegatedFrame() { |
| if (layer_.get()) |
| DestroyDelegatedContent(); |
| frame_evictor_->DiscardedFrame(); |
| + // We are evicting the delegated frame, |
| + // so there should be no pending readback requests |
| + DCHECK(readbacks_waiting_for_frame_.empty()); |
| } |
| bool RenderWidgetHostViewAndroid::HasAcceleratedSurface( |
| @@ -1518,6 +1567,8 @@ void RenderWidgetHostViewAndroid::OnLostResources() { |
| if (layer_.get()) |
| DestroyDelegatedContent(); |
| DCHECK(ack_callbacks_.empty()); |
| + // We should not loose a frame if we have readback requests pending. |
| + DCHECK(readbacks_waiting_for_frame_.empty()); |
| } |
| // static |