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

Side by Side 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: Created 6 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_widget_host_view_android.h" 5 #include "content/browser/renderer_host/render_widget_host_view_android.h"
6 6
7 #include <android/bitmap.h> 7 #include <android/bitmap.h>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 observing_root_window_(false) { 205 observing_root_window_(false) {
206 host_->SetView(this); 206 host_->SetView(this);
207 SetContentViewCore(content_view_core); 207 SetContentViewCore(content_view_core);
208 ImageTransportFactoryAndroid::AddObserver(this); 208 ImageTransportFactoryAndroid::AddObserver(this);
209 } 209 }
210 210
211 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { 211 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
212 ImageTransportFactoryAndroid::RemoveObserver(this); 212 ImageTransportFactoryAndroid::RemoveObserver(this);
213 SetContentViewCore(NULL); 213 SetContentViewCore(NULL);
214 DCHECK(ack_callbacks_.empty()); 214 DCHECK(ack_callbacks_.empty());
215 DCHECK(readbacks_waiting_for_frame_.empty());
215 if (resource_collection_.get()) 216 if (resource_collection_.get())
216 resource_collection_->SetClient(NULL); 217 resource_collection_->SetClient(NULL);
217 } 218 }
218 219
219 220
220 bool RenderWidgetHostViewAndroid::OnMessageReceived( 221 bool RenderWidgetHostViewAndroid::OnMessageReceived(
221 const IPC::Message& message) { 222 const IPC::Message& message) {
222 bool handled = true; 223 bool handled = true;
223 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) 224 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
224 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) 225 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { 289 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
289 // Ignore the given size as only the Java code has the power to 290 // Ignore the given size as only the Java code has the power to
290 // resize the view on Android. 291 // resize the view on Android.
291 default_size_ = size; 292 default_size_ = size;
292 } 293 }
293 294
294 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { 295 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
295 SetSize(rect.size()); 296 SetSize(rect.size());
296 } 297 }
297 298
299 void RenderWidgetHostViewAndroid::ProcessPendingReadbackRequests() {
no sievers 2014/07/28 17:07:06 Ok, I see, so this doesn't actually do the readbac
sivag 2014/08/01 10:10:20 1. changed ProcessPendingReadbackRequests ->AbortP
300 while (!readbacks_waiting_for_frame_.empty()) {
301 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
302 readback_request.GetResultCallback().Run(false, SkBitmap());
303 readbacks_waiting_for_frame_.pop();
304 }
305 }
306
307 void RenderWidgetHostViewAndroid::WaitForValidFrameArrival(
308 const ReadbackRequest& readback_request) {
309 readbacks_waiting_for_frame_.push(readback_request);
no sievers 2014/07/28 17:07:06 nit: don't need a method for this one line of code
sivag 2014/08/01 10:10:20 Done.
310 }
311
298 void RenderWidgetHostViewAndroid::GetScaledContentBitmap( 312 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
299 float scale, 313 float scale,
300 SkColorType color_type, 314 SkColorType color_type,
301 gfx::Rect src_subrect, 315 gfx::Rect src_subrect,
302 const base::Callback<void(bool, const SkBitmap&)>& result_callback) { 316 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
303 if (!host_ || host_->is_hidden()) { 317 if (!host_ || host_->is_hidden()) {
304 result_callback.Run(false, SkBitmap()); 318 result_callback.Run(false, SkBitmap());
305 return; 319 return;
306 } 320 }
307 if (!IsSurfaceAvailableForCopy()) { 321 if (!IsSurfaceAvailableForCopy()) {
308 // TODO(Sikugu): allow a read-back request to wait for a first frame if it 322 // The view is visible, probably the frame has not yet arrived.
309 // was invoked while no frame was received yet 323 // Just add the ReadbackRequest to queue and wait for frame arrival
310 result_callback.Run(false, SkBitmap()); 324 // to get this request processed.
325 WaitForValidFrameArrival(
326 ReadbackRequest(scale, color_type, src_subrect, result_callback));
327 // TODO(sikugu): Do we need to have a timeout for a readback here?
no sievers 2014/07/28 17:07:06 I don't *think* we need a timeout. We know we are
sivag 2014/08/01 10:10:20 Done.
311 return; 328 return;
312 } 329 }
313 330
314 gfx::Size bounds = layer_->bounds(); 331 gfx::Size bounds = layer_->bounds();
315 if (src_subrect.IsEmpty()) 332 if (src_subrect.IsEmpty())
316 src_subrect = gfx::Rect(bounds); 333 src_subrect = gfx::Rect(bounds);
317 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width()); 334 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
318 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height()); 335 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
319 const gfx::Display& display = 336 const gfx::Display& display =
320 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 337 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
321 float device_scale_factor = display.device_scale_factor(); 338 float device_scale_factor = display.device_scale_factor();
322 DCHECK_GT(device_scale_factor, 0); 339 DCHECK_GT(device_scale_factor, 0);
323 gfx::Size dst_size( 340 gfx::Size dst_size(
324 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor))); 341 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
325 CopyFromCompositingSurface( 342 CopyFromCompositingSurface(
326 src_subrect, dst_size, result_callback, color_type); 343 src_subrect, dst_size, result_callback, color_type);
327 } 344 }
328 345
329 bool RenderWidgetHostViewAndroid::HasValidFrame() const { 346 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
330 if (!content_view_core_) 347 if (!content_view_core_)
331 return false; 348 return false;
332 if (!layer_) 349 if (!layer_)
333 return false; 350 return false;
334 351
335 if (texture_size_in_layer_.IsEmpty()) 352 if (texture_size_in_layer_.IsEmpty())
336 return false; 353 return false;
337 354 // This tell us whether a valid frame has arrived or not.
338 if (!frame_evictor_->HasFrame()) 355 if (!frame_evictor_->HasFrame())
339 return false; 356 return false;
340 357
341 return true; 358 return true;
342 } 359 }
343 360
344 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const { 361 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
345 return content_view_core_->GetViewAndroid(); 362 return content_view_core_->GetViewAndroid();
346 } 363 }
347 364
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 419
403 void RenderWidgetHostViewAndroid::Hide() { 420 void RenderWidgetHostViewAndroid::Hide() {
404 if (!is_showing_) 421 if (!is_showing_)
405 return; 422 return;
406 423
407 is_showing_ = false; 424 is_showing_ = false;
408 if (layer_ && locks_on_frame_count_ == 0) 425 if (layer_ && locks_on_frame_count_ == 0)
409 layer_->SetHideLayerAndSubtree(true); 426 layer_->SetHideLayerAndSubtree(true);
410 427
411 frame_evictor_->SetVisible(false); 428 frame_evictor_->SetVisible(false);
429 // We are hiding a renderer and any readback requests pending on frame arrival
430 // need to be addressed here.
431 ProcessPendingReadbackRequests();
no sievers 2014/07/28 17:07:06 It would be nice if we could allow deferring the r
no sievers 2014/07/28 17:08:33 Scrap that comment. We don't allow locking the sur
sivag 2014/08/01 10:10:20 Done.
sivag 2014/08/01 10:10:20 Done.
412 WasHidden(); 432 WasHidden();
413 } 433 }
414 434
415 bool RenderWidgetHostViewAndroid::IsShowing() { 435 bool RenderWidgetHostViewAndroid::IsShowing() {
416 // ContentViewCoreImpl represents the native side of the Java 436 // ContentViewCoreImpl represents the native side of the Java
417 // ContentViewCore. It being NULL means that it is not attached 437 // ContentViewCore. It being NULL means that it is not attached
418 // to the View system yet, so we treat this RWHVA as hidden. 438 // to the View system yet, so we treat this RWHVA as hidden.
419 return is_showing_ && content_view_core_; 439 return is_showing_ && content_view_core_;
420 } 440 }
421 441
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() { 850 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
831 if (ack_callbacks_.size()) 851 if (ack_callbacks_.size())
832 return; 852 return;
833 SendReturnedDelegatedResources(last_output_surface_id_); 853 SendReturnedDelegatedResources(last_output_surface_id_);
834 } 854 }
835 855
836 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { 856 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
837 RemoveLayers(); 857 RemoveLayers();
838 frame_provider_ = NULL; 858 frame_provider_ = NULL;
839 layer_ = NULL; 859 layer_ = NULL;
860 ProcessPendingReadbackRequests();
no sievers 2014/07/28 17:07:06 Which case is this handling? I'm not sure it's alw
sivag 2014/08/01 10:10:20 If any of above functions gets triggered, they wil
840 } 861 }
841 862
842 void RenderWidgetHostViewAndroid::SwapDelegatedFrame( 863 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
843 uint32 output_surface_id, 864 uint32 output_surface_id,
844 scoped_ptr<cc::DelegatedFrameData> frame_data) { 865 scoped_ptr<cc::DelegatedFrameData> frame_data) {
845 bool has_content = !texture_size_in_layer_.IsEmpty(); 866 bool has_content = !texture_size_in_layer_.IsEmpty();
846 867
847 if (output_surface_id != last_output_surface_id_) { 868 if (output_surface_id != last_output_surface_id_) {
848 // Drop the cc::DelegatedFrameResourceCollection so that we will not return 869 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
849 // any resources from the old output surface with the new output surface id. 870 // any resources from the old output surface with the new output surface id.
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 973
953 // As the metadata update may trigger view invalidation, always call it after 974 // As the metadata update may trigger view invalidation, always call it after
954 // any potential compositor scheduling. 975 // any potential compositor scheduling.
955 OnFrameMetadataUpdated(frame->metadata); 976 OnFrameMetadataUpdated(frame->metadata);
956 } 977 }
957 978
958 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( 979 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
959 uint32 output_surface_id, 980 uint32 output_surface_id,
960 scoped_ptr<cc::CompositorFrame> frame) { 981 scoped_ptr<cc::CompositorFrame> frame) {
961 InternalSwapCompositorFrame(output_surface_id, frame.Pass()); 982 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
983 if (!readbacks_waiting_for_frame_.empty() && HasValidFrame()) {
984 while (!readbacks_waiting_for_frame_.empty()) {
985 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
986 GetScaledContentBitmap(readback_request.GetScale(),
987 readback_request.GetColorFormat(),
988 readback_request.GetCaptureRect(),
989 readback_request.GetResultCallback());
990 readbacks_waiting_for_frame_.pop();
991 }
no sievers 2014/07/28 17:07:06 Can you move this to the end of InternalSwapCompos
sivag 2014/08/01 10:10:20 Done.
992 }
962 } 993 }
963 994
964 void RenderWidgetHostViewAndroid::RetainFrame( 995 void RenderWidgetHostViewAndroid::RetainFrame(
965 uint32 output_surface_id, 996 uint32 output_surface_id,
966 scoped_ptr<cc::CompositorFrame> frame) { 997 scoped_ptr<cc::CompositorFrame> frame) {
967 DCHECK(locks_on_frame_count_); 998 DCHECK(locks_on_frame_count_);
968 999
969 // Store the incoming frame so that it can be swapped when all the locks have 1000 // Store the incoming frame so that it can be swapped when all the locks have
970 // been released. If there is already a stored frame, then replace and skip 1001 // been released. If there is already a stored frame, then replace and skip
971 // the previous one but make sure we still eventually send the ACK. Holding 1002 // the previous one but make sure we still eventually send the ACK. Holding
(...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after
1641 results->orientationAngle = display.RotationAsDegree(); 1672 results->orientationAngle = display.RotationAsDegree();
1642 results->orientationType = 1673 results->orientationType =
1643 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display); 1674 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
1644 gfx::DeviceDisplayInfo info; 1675 gfx::DeviceDisplayInfo info;
1645 results->depth = info.GetBitsPerPixel(); 1676 results->depth = info.GetBitsPerPixel();
1646 results->depthPerComponent = info.GetBitsPerComponent(); 1677 results->depthPerComponent = info.GetBitsPerComponent();
1647 results->isMonochrome = (results->depthPerComponent == 0); 1678 results->isMonochrome = (results->depthPerComponent == 0);
1648 } 1679 }
1649 1680
1650 } // namespace content 1681 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698