Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(699)

Unified Diff: content/browser/renderer_host/render_widget_host_view_android.cc

Issue 415773007: Android:Allow a read-back request to wait for a first frame (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move explicit constructor body to cc files. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698