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

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: addressed the review comments. 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
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_android.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) { 210 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) {
211 float window_width_dip = 211 float window_width_dip =
212 frame_metadata.page_scale_factor * 212 frame_metadata.page_scale_factor *
213 frame_metadata.scrollable_viewport_size.width(); 213 frame_metadata.scrollable_viewport_size.width();
214 float content_width_css = frame_metadata.root_layer_size.width(); 214 float content_width_css = frame_metadata.root_layer_size.width();
215 return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon; 215 return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
216 } 216 }
217 217
218 } // anonymous namespace 218 } // anonymous namespace
219 219
220 ReadbackRequest::ReadbackRequest(
221 float scale,
222 SkColorType color_type,
223 gfx::Rect src_subrect,
224 const base::Callback<void(bool, const SkBitmap&)>& result_callback)
225 : scale_(scale),
226 color_type_(color_type),
227 src_subrect_(src_subrect),
228 result_callback_(result_callback) {
229 }
230
231 ReadbackRequest::ReadbackRequest() {
232 }
233
234 ReadbackRequest::~ReadbackRequest() {
235 }
236
220 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo( 237 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
221 uint32 output_id, 238 uint32 output_id,
222 scoped_ptr<cc::CompositorFrame> output_frame) 239 scoped_ptr<cc::CompositorFrame> output_frame)
223 : output_surface_id(output_id), frame(output_frame.Pass()) {} 240 : output_surface_id(output_id), frame(output_frame.Pass()) {}
224 241
225 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {} 242 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
226 243
227 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( 244 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
228 RenderWidgetHostImpl* widget_host, 245 RenderWidgetHostImpl* widget_host,
229 ContentViewCoreImpl* content_view_core) 246 ContentViewCoreImpl* content_view_core)
(...skipping 22 matching lines...) Expand all
252 observing_root_window_(false) { 269 observing_root_window_(false) {
253 host_->SetView(this); 270 host_->SetView(this);
254 SetContentViewCore(content_view_core); 271 SetContentViewCore(content_view_core);
255 ImageTransportFactoryAndroid::AddObserver(this); 272 ImageTransportFactoryAndroid::AddObserver(this);
256 } 273 }
257 274
258 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { 275 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
259 ImageTransportFactoryAndroid::RemoveObserver(this); 276 ImageTransportFactoryAndroid::RemoveObserver(this);
260 SetContentViewCore(NULL); 277 SetContentViewCore(NULL);
261 DCHECK(ack_callbacks_.empty()); 278 DCHECK(ack_callbacks_.empty());
279 DCHECK(readbacks_waiting_for_frame_.empty());
262 if (resource_collection_.get()) 280 if (resource_collection_.get())
263 resource_collection_->SetClient(NULL); 281 resource_collection_->SetClient(NULL);
264 } 282 }
265 283
266 284
267 bool RenderWidgetHostViewAndroid::OnMessageReceived( 285 bool RenderWidgetHostViewAndroid::OnMessageReceived(
268 const IPC::Message& message) { 286 const IPC::Message& message) {
269 bool handled = true; 287 bool handled = true;
270 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) 288 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
271 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) 289 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent)
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) { 353 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
336 // Ignore the given size as only the Java code has the power to 354 // Ignore the given size as only the Java code has the power to
337 // resize the view on Android. 355 // resize the view on Android.
338 default_size_ = size; 356 default_size_ = size;
339 } 357 }
340 358
341 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { 359 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
342 SetSize(rect.size()); 360 SetSize(rect.size());
343 } 361 }
344 362
363 void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() {
364 while (!readbacks_waiting_for_frame_.empty()) {
365 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
366 readback_request.GetResultCallback().Run(false, SkBitmap());
367 readbacks_waiting_for_frame_.pop();
368 }
369 }
370
345 void RenderWidgetHostViewAndroid::GetScaledContentBitmap( 371 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
346 float scale, 372 float scale,
347 SkColorType color_type, 373 SkColorType color_type,
348 gfx::Rect src_subrect, 374 gfx::Rect src_subrect,
349 const base::Callback<void(bool, const SkBitmap&)>& result_callback) { 375 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
350 if (!host_ || host_->is_hidden()) { 376 if (!host_ || host_->is_hidden()) {
351 result_callback.Run(false, SkBitmap()); 377 result_callback.Run(false, SkBitmap());
352 return; 378 return;
353 } 379 }
354 if (!IsSurfaceAvailableForCopy()) { 380 if (!IsSurfaceAvailableForCopy()) {
355 // TODO(Sikugu): allow a read-back request to wait for a first frame if it 381 // The view is visible, probably the frame has not yet arrived.
356 // was invoked while no frame was received yet 382 // Just add the ReadbackRequest to queue and wait for frame arrival
357 result_callback.Run(false, SkBitmap()); 383 // to get this request processed.
384 readbacks_waiting_for_frame_.push(
385 ReadbackRequest(scale, color_type, src_subrect, result_callback));
358 return; 386 return;
359 } 387 }
360 388
361 gfx::Size bounds = layer_->bounds(); 389 gfx::Size bounds = layer_->bounds();
362 if (src_subrect.IsEmpty()) 390 if (src_subrect.IsEmpty())
363 src_subrect = gfx::Rect(bounds); 391 src_subrect = gfx::Rect(bounds);
364 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width()); 392 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
365 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height()); 393 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
366 const gfx::Display& display = 394 const gfx::Display& display =
367 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 395 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
368 float device_scale_factor = display.device_scale_factor(); 396 float device_scale_factor = display.device_scale_factor();
369 DCHECK_GT(device_scale_factor, 0); 397 DCHECK_GT(device_scale_factor, 0);
370 gfx::Size dst_size( 398 gfx::Size dst_size(
371 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor))); 399 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
372 CopyFromCompositingSurface( 400 CopyFromCompositingSurface(
373 src_subrect, dst_size, result_callback, color_type); 401 src_subrect, dst_size, result_callback, color_type);
374 } 402 }
375 403
376 bool RenderWidgetHostViewAndroid::HasValidFrame() const { 404 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
377 if (!content_view_core_) 405 if (!content_view_core_)
378 return false; 406 return false;
379 if (!layer_) 407 if (!layer_)
380 return false; 408 return false;
381 409
382 if (texture_size_in_layer_.IsEmpty()) 410 if (texture_size_in_layer_.IsEmpty())
383 return false; 411 return false;
384 412 // This tell us whether a valid frame has arrived or not.
385 if (!frame_evictor_->HasFrame()) 413 if (!frame_evictor_->HasFrame())
386 return false; 414 return false;
387 415
388 return true; 416 return true;
389 } 417 }
390 418
391 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const { 419 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
392 return content_view_core_->GetViewAndroid(); 420 return content_view_core_->GetViewAndroid();
393 } 421 }
394 422
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 478
451 void RenderWidgetHostViewAndroid::Hide() { 479 void RenderWidgetHostViewAndroid::Hide() {
452 if (!is_showing_) 480 if (!is_showing_)
453 return; 481 return;
454 482
455 is_showing_ = false; 483 is_showing_ = false;
456 if (layer_ && locks_on_frame_count_ == 0) 484 if (layer_ && locks_on_frame_count_ == 0)
457 layer_->SetHideLayerAndSubtree(true); 485 layer_->SetHideLayerAndSubtree(true);
458 486
459 frame_evictor_->SetVisible(false); 487 frame_evictor_->SetVisible(false);
488 // We don't know if we will ever get a frame if we are hiding the renderer, so
489 // we need to cancel all requests
490 AbortPendingReadbackRequests();
460 WasHidden(); 491 WasHidden();
461 } 492 }
462 493
463 bool RenderWidgetHostViewAndroid::IsShowing() { 494 bool RenderWidgetHostViewAndroid::IsShowing() {
464 // ContentViewCoreImpl represents the native side of the Java 495 // ContentViewCoreImpl represents the native side of the Java
465 // ContentViewCore. It being NULL means that it is not attached 496 // ContentViewCore. It being NULL means that it is not attached
466 // to the View system yet, so we treat this RWHVA as hidden. 497 // to the View system yet, so we treat this RWHVA as hidden.
467 return is_showing_ && content_view_core_; 498 return is_showing_ && content_view_core_;
468 } 499 }
469 500
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() { 922 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
892 if (ack_callbacks_.size()) 923 if (ack_callbacks_.size())
893 return; 924 return;
894 SendReturnedDelegatedResources(last_output_surface_id_); 925 SendReturnedDelegatedResources(last_output_surface_id_);
895 } 926 }
896 927
897 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { 928 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
898 RemoveLayers(); 929 RemoveLayers();
899 frame_provider_ = NULL; 930 frame_provider_ = NULL;
900 layer_ = NULL; 931 layer_ = NULL;
932 // This gets called when ever any eviction, loosing resources, swapping
933 // problems are encountered and so we abort any pending readbacks here.
934 AbortPendingReadbackRequests();
901 } 935 }
902 936
903 void RenderWidgetHostViewAndroid::SwapDelegatedFrame( 937 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
904 uint32 output_surface_id, 938 uint32 output_surface_id,
905 scoped_ptr<cc::DelegatedFrameData> frame_data) { 939 scoped_ptr<cc::DelegatedFrameData> frame_data) {
906 bool has_content = !texture_size_in_layer_.IsEmpty(); 940 bool has_content = !texture_size_in_layer_.IsEmpty();
907 941
908 if (output_surface_id != last_output_surface_id_) { 942 if (output_surface_id != last_output_surface_id_) {
909 // Drop the cc::DelegatedFrameResourceCollection so that we will not return 943 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
910 // any resources from the old output surface with the new output surface id. 944 // any resources from the old output surface with the new output surface id.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 frame->delegated_frame_data->render_pass_list.back(); 1043 frame->delegated_frame_data->render_pass_list.back();
1010 texture_size_in_layer_ = root_pass->output_rect.size(); 1044 texture_size_in_layer_ = root_pass->output_rect.size();
1011 ComputeContentsSize(frame->metadata); 1045 ComputeContentsSize(frame->metadata);
1012 1046
1013 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass()); 1047 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
1014 frame_evictor_->SwappedFrame(!host_->is_hidden()); 1048 frame_evictor_->SwappedFrame(!host_->is_hidden());
1015 1049
1016 // As the metadata update may trigger view invalidation, always call it after 1050 // As the metadata update may trigger view invalidation, always call it after
1017 // any potential compositor scheduling. 1051 // any potential compositor scheduling.
1018 OnFrameMetadataUpdated(frame->metadata); 1052 OnFrameMetadataUpdated(frame->metadata);
1053 // Check if we have any pending readbacks, see if we have a frame available
1054 // and process them here.
1055 if (!readbacks_waiting_for_frame_.empty()) {
1056 while (!readbacks_waiting_for_frame_.empty()) {
1057 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
1058 GetScaledContentBitmap(readback_request.GetScale(),
1059 readback_request.GetColorFormat(),
1060 readback_request.GetCaptureRect(),
1061 readback_request.GetResultCallback());
1062 readbacks_waiting_for_frame_.pop();
1063 }
1064 }
1019 } 1065 }
1020 1066
1021 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( 1067 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
1022 uint32 output_surface_id, 1068 uint32 output_surface_id,
1023 scoped_ptr<cc::CompositorFrame> frame) { 1069 scoped_ptr<cc::CompositorFrame> frame) {
1024 InternalSwapCompositorFrame(output_surface_id, frame.Pass()); 1070 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
1025 } 1071 }
1026 1072
1027 void RenderWidgetHostViewAndroid::RetainFrame( 1073 void RenderWidgetHostViewAndroid::RetainFrame(
1028 uint32 output_surface_id, 1074 uint32 output_surface_id,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 } 1282 }
1237 1283
1238 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() { 1284 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
1239 NOTREACHED(); 1285 NOTREACHED();
1240 } 1286 }
1241 1287
1242 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() { 1288 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1243 if (layer_.get()) 1289 if (layer_.get())
1244 DestroyDelegatedContent(); 1290 DestroyDelegatedContent();
1245 frame_evictor_->DiscardedFrame(); 1291 frame_evictor_->DiscardedFrame();
1292 // We are evicting the delegated frame,
1293 // so there should be no pending readback requests
1294 DCHECK(readbacks_waiting_for_frame_.empty());
1246 } 1295 }
1247 1296
1248 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface( 1297 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1249 const gfx::Size& desired_size) { 1298 const gfx::Size& desired_size) {
1250 NOTREACHED(); 1299 NOTREACHED();
1251 return false; 1300 return false;
1252 } 1301 }
1253 1302
1254 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) { 1303 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1255 // ScreenInfo isn't tied to the widget on Android. Always return the default. 1304 // ScreenInfo isn't tied to the widget on Android. Always return the default.
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) { 1650 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
1602 if (Animate(begin_frame_time)) 1651 if (Animate(begin_frame_time))
1603 SetNeedsAnimate(); 1652 SetNeedsAnimate();
1604 } 1653 }
1605 1654
1606 void RenderWidgetHostViewAndroid::OnLostResources() { 1655 void RenderWidgetHostViewAndroid::OnLostResources() {
1607 ReleaseLocksOnSurface(); 1656 ReleaseLocksOnSurface();
1608 if (layer_.get()) 1657 if (layer_.get())
1609 DestroyDelegatedContent(); 1658 DestroyDelegatedContent();
1610 DCHECK(ack_callbacks_.empty()); 1659 DCHECK(ack_callbacks_.empty());
1660 // We should not loose a frame if we have readback requests pending.
1661 DCHECK(readbacks_waiting_for_frame_.empty());
1611 } 1662 }
1612 1663
1613 // static 1664 // static
1614 void 1665 void
1615 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback( 1666 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1616 const gfx::Size& dst_size_in_pixel, 1667 const gfx::Size& dst_size_in_pixel,
1617 const SkColorType color_type, 1668 const SkColorType color_type,
1618 const base::TimeTicks& start_time, 1669 const base::TimeTicks& start_time,
1619 scoped_refptr<cc::Layer> readback_layer, 1670 scoped_refptr<cc::Layer> readback_layer,
1620 const base::Callback<void(bool, const SkBitmap&)>& callback, 1671 const base::Callback<void(bool, const SkBitmap&)>& callback,
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1742 results->orientationAngle = display.RotationAsDegree(); 1793 results->orientationAngle = display.RotationAsDegree();
1743 results->orientationType = 1794 results->orientationType =
1744 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display); 1795 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
1745 gfx::DeviceDisplayInfo info; 1796 gfx::DeviceDisplayInfo info;
1746 results->depth = info.GetBitsPerPixel(); 1797 results->depth = info.GetBitsPerPixel();
1747 results->depthPerComponent = info.GetBitsPerComponent(); 1798 results->depthPerComponent = info.GetBitsPerComponent();
1748 results->isMonochrome = (results->depthPerComponent == 0); 1799 results->isMonochrome = (results->depthPerComponent == 0);
1749 } 1800 }
1750 1801
1751 } // namespace content 1802 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_android.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698