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

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: Move explicit constructor body to cc files. 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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) { 163 bool HasMobileViewport(const cc::CompositorFrameMetadata& frame_metadata) {
164 float window_width_dip = 164 float window_width_dip =
165 frame_metadata.page_scale_factor * 165 frame_metadata.page_scale_factor *
166 frame_metadata.scrollable_viewport_size.width(); 166 frame_metadata.scrollable_viewport_size.width();
167 float content_width_css = frame_metadata.root_layer_size.width(); 167 float content_width_css = frame_metadata.root_layer_size.width();
168 return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon; 168 return content_width_css <= window_width_dip + kMobileViewportWidthEpsilon;
169 } 169 }
170 170
171 } // anonymous namespace 171 } // anonymous namespace
172 172
173 ReadbackRequest::ReadbackRequest(
174 float scale,
175 SkColorType color_type,
176 gfx::Rect src_subrect,
177 const base::Callback<void(bool, const SkBitmap&)>& result_callback)
178 : scale_(scale),
179 color_type_(color_type),
180 src_subrect_(src_subrect),
181 result_callback_(result_callback) {
182 }
183
184 ReadbackRequest::ReadbackRequest() {
185 }
186
187 ReadbackRequest::~ReadbackRequest() {
188 }
189
173 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo( 190 RenderWidgetHostViewAndroid::LastFrameInfo::LastFrameInfo(
174 uint32 output_id, 191 uint32 output_id,
175 scoped_ptr<cc::CompositorFrame> output_frame) 192 scoped_ptr<cc::CompositorFrame> output_frame)
176 : output_surface_id(output_id), frame(output_frame.Pass()) {} 193 : output_surface_id(output_id), frame(output_frame.Pass()) {}
177 194
178 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {} 195 RenderWidgetHostViewAndroid::LastFrameInfo::~LastFrameInfo() {}
179 196
180 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( 197 RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
181 RenderWidgetHostImpl* widget_host, 198 RenderWidgetHostImpl* widget_host,
182 ContentViewCoreImpl* content_view_core) 199 ContentViewCoreImpl* content_view_core)
(...skipping 22 matching lines...) Expand all
205 observing_root_window_(false) { 222 observing_root_window_(false) {
206 host_->SetView(this); 223 host_->SetView(this);
207 SetContentViewCore(content_view_core); 224 SetContentViewCore(content_view_core);
208 ImageTransportFactoryAndroid::AddObserver(this); 225 ImageTransportFactoryAndroid::AddObserver(this);
209 } 226 }
210 227
211 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() { 228 RenderWidgetHostViewAndroid::~RenderWidgetHostViewAndroid() {
212 ImageTransportFactoryAndroid::RemoveObserver(this); 229 ImageTransportFactoryAndroid::RemoveObserver(this);
213 SetContentViewCore(NULL); 230 SetContentViewCore(NULL);
214 DCHECK(ack_callbacks_.empty()); 231 DCHECK(ack_callbacks_.empty());
232 DCHECK(readbacks_waiting_for_frame_.empty());
215 if (resource_collection_.get()) 233 if (resource_collection_.get())
216 resource_collection_->SetClient(NULL); 234 resource_collection_->SetClient(NULL);
217 } 235 }
218 236
219 237
220 bool RenderWidgetHostViewAndroid::OnMessageReceived( 238 bool RenderWidgetHostViewAndroid::OnMessageReceived(
221 const IPC::Message& message) { 239 const IPC::Message& message) {
222 bool handled = true; 240 bool handled = true;
223 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message) 241 IPC_BEGIN_MESSAGE_MAP(RenderWidgetHostViewAndroid, message)
224 IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) 242 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) { 306 void RenderWidgetHostViewAndroid::SetSize(const gfx::Size& size) {
289 // Ignore the given size as only the Java code has the power to 307 // Ignore the given size as only the Java code has the power to
290 // resize the view on Android. 308 // resize the view on Android.
291 default_size_ = size; 309 default_size_ = size;
292 } 310 }
293 311
294 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) { 312 void RenderWidgetHostViewAndroid::SetBounds(const gfx::Rect& rect) {
295 SetSize(rect.size()); 313 SetSize(rect.size());
296 } 314 }
297 315
316 void RenderWidgetHostViewAndroid::AbortPendingReadbackRequests() {
317 while (!readbacks_waiting_for_frame_.empty()) {
318 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
319 readback_request.GetResultCallback().Run(false, SkBitmap());
320 readbacks_waiting_for_frame_.pop();
321 }
322 }
323
298 void RenderWidgetHostViewAndroid::GetScaledContentBitmap( 324 void RenderWidgetHostViewAndroid::GetScaledContentBitmap(
299 float scale, 325 float scale,
300 SkColorType color_type, 326 SkColorType color_type,
301 gfx::Rect src_subrect, 327 gfx::Rect src_subrect,
302 const base::Callback<void(bool, const SkBitmap&)>& result_callback) { 328 const base::Callback<void(bool, const SkBitmap&)>& result_callback) {
303 if (!host_ || host_->is_hidden()) { 329 if (!host_ || host_->is_hidden()) {
304 result_callback.Run(false, SkBitmap()); 330 result_callback.Run(false, SkBitmap());
305 return; 331 return;
306 } 332 }
307 if (!IsSurfaceAvailableForCopy()) { 333 if (!IsSurfaceAvailableForCopy()) {
308 // TODO(Sikugu): allow a read-back request to wait for a first frame if it 334 // The view is visible, probably the frame has not yet arrived.
309 // was invoked while no frame was received yet 335 // Just add the ReadbackRequest to queue and wait for frame arrival
310 result_callback.Run(false, SkBitmap()); 336 // to get this request processed.
337 readbacks_waiting_for_frame_.push(
338 ReadbackRequest(scale, color_type, src_subrect, result_callback));
311 return; 339 return;
312 } 340 }
313 341
314 gfx::Size bounds = layer_->bounds(); 342 gfx::Size bounds = layer_->bounds();
315 if (src_subrect.IsEmpty()) 343 if (src_subrect.IsEmpty())
316 src_subrect = gfx::Rect(bounds); 344 src_subrect = gfx::Rect(bounds);
317 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width()); 345 DCHECK_LE(src_subrect.width() + src_subrect.x(), bounds.width());
318 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height()); 346 DCHECK_LE(src_subrect.height() + src_subrect.y(), bounds.height());
319 const gfx::Display& display = 347 const gfx::Display& display =
320 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay(); 348 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
321 float device_scale_factor = display.device_scale_factor(); 349 float device_scale_factor = display.device_scale_factor();
322 DCHECK_GT(device_scale_factor, 0); 350 DCHECK_GT(device_scale_factor, 0);
323 gfx::Size dst_size( 351 gfx::Size dst_size(
324 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor))); 352 gfx::ToCeiledSize(gfx::ScaleSize(bounds, scale / device_scale_factor)));
325 CopyFromCompositingSurface( 353 CopyFromCompositingSurface(
326 src_subrect, dst_size, result_callback, color_type); 354 src_subrect, dst_size, result_callback, color_type);
327 } 355 }
328 356
329 bool RenderWidgetHostViewAndroid::HasValidFrame() const { 357 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
330 if (!content_view_core_) 358 if (!content_view_core_)
331 return false; 359 return false;
332 if (!layer_) 360 if (!layer_)
333 return false; 361 return false;
334 362
335 if (texture_size_in_layer_.IsEmpty()) 363 if (texture_size_in_layer_.IsEmpty())
336 return false; 364 return false;
337 365 // This tell us whether a valid frame has arrived or not.
338 if (!frame_evictor_->HasFrame()) 366 if (!frame_evictor_->HasFrame())
339 return false; 367 return false;
340 368
341 return true; 369 return true;
342 } 370 }
343 371
344 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const { 372 gfx::NativeView RenderWidgetHostViewAndroid::GetNativeView() const {
345 return content_view_core_->GetViewAndroid(); 373 return content_view_core_->GetViewAndroid();
346 } 374 }
347 375
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 430
403 void RenderWidgetHostViewAndroid::Hide() { 431 void RenderWidgetHostViewAndroid::Hide() {
404 if (!is_showing_) 432 if (!is_showing_)
405 return; 433 return;
406 434
407 is_showing_ = false; 435 is_showing_ = false;
408 if (layer_ && locks_on_frame_count_ == 0) 436 if (layer_ && locks_on_frame_count_ == 0)
409 layer_->SetHideLayerAndSubtree(true); 437 layer_->SetHideLayerAndSubtree(true);
410 438
411 frame_evictor_->SetVisible(false); 439 frame_evictor_->SetVisible(false);
440 // We are hiding a renderer and any readback requests pending on frame arrival
441 // 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.
442 AbortPendingReadbackRequests();
412 WasHidden(); 443 WasHidden();
413 } 444 }
414 445
415 bool RenderWidgetHostViewAndroid::IsShowing() { 446 bool RenderWidgetHostViewAndroid::IsShowing() {
416 // ContentViewCoreImpl represents the native side of the Java 447 // ContentViewCoreImpl represents the native side of the Java
417 // ContentViewCore. It being NULL means that it is not attached 448 // ContentViewCore. It being NULL means that it is not attached
418 // to the View system yet, so we treat this RWHVA as hidden. 449 // to the View system yet, so we treat this RWHVA as hidden.
419 return is_showing_ && content_view_core_; 450 return is_showing_ && content_view_core_;
420 } 451 }
421 452
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() { 873 void RenderWidgetHostViewAndroid::UnusedResourcesAreAvailable() {
843 if (ack_callbacks_.size()) 874 if (ack_callbacks_.size())
844 return; 875 return;
845 SendReturnedDelegatedResources(last_output_surface_id_); 876 SendReturnedDelegatedResources(last_output_surface_id_);
846 } 877 }
847 878
848 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() { 879 void RenderWidgetHostViewAndroid::DestroyDelegatedContent() {
849 RemoveLayers(); 880 RemoveLayers();
850 frame_provider_ = NULL; 881 frame_provider_ = NULL;
851 layer_ = NULL; 882 layer_ = NULL;
883 // This gets called when ever any eviction, loosing resources, swapping
884 // problems are encountered and so we abort any pending readbacks here.
885 AbortPendingReadbackRequests();
852 } 886 }
853 887
854 void RenderWidgetHostViewAndroid::SwapDelegatedFrame( 888 void RenderWidgetHostViewAndroid::SwapDelegatedFrame(
855 uint32 output_surface_id, 889 uint32 output_surface_id,
856 scoped_ptr<cc::DelegatedFrameData> frame_data) { 890 scoped_ptr<cc::DelegatedFrameData> frame_data) {
857 bool has_content = !texture_size_in_layer_.IsEmpty(); 891 bool has_content = !texture_size_in_layer_.IsEmpty();
858 892
859 if (output_surface_id != last_output_surface_id_) { 893 if (output_surface_id != last_output_surface_id_) {
860 // Drop the cc::DelegatedFrameResourceCollection so that we will not return 894 // Drop the cc::DelegatedFrameResourceCollection so that we will not return
861 // any resources from the old output surface with the new output surface id. 895 // any resources from the old output surface with the new output surface id.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 frame->delegated_frame_data->render_pass_list.back(); 992 frame->delegated_frame_data->render_pass_list.back();
959 texture_size_in_layer_ = root_pass->output_rect.size(); 993 texture_size_in_layer_ = root_pass->output_rect.size();
960 ComputeContentsSize(frame->metadata); 994 ComputeContentsSize(frame->metadata);
961 995
962 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass()); 996 SwapDelegatedFrame(output_surface_id, frame->delegated_frame_data.Pass());
963 frame_evictor_->SwappedFrame(!host_->is_hidden()); 997 frame_evictor_->SwappedFrame(!host_->is_hidden());
964 998
965 // As the metadata update may trigger view invalidation, always call it after 999 // As the metadata update may trigger view invalidation, always call it after
966 // any potential compositor scheduling. 1000 // any potential compositor scheduling.
967 OnFrameMetadataUpdated(frame->metadata); 1001 OnFrameMetadataUpdated(frame->metadata);
1002 // Check if we have any pending readbacks, see if we have a frame available
1003 // and process them here.
1004 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.
1005 while (!readbacks_waiting_for_frame_.empty()) {
1006 ReadbackRequest& readback_request = readbacks_waiting_for_frame_.front();
1007 GetScaledContentBitmap(readback_request.GetScale(),
1008 readback_request.GetColorFormat(),
1009 readback_request.GetCaptureRect(),
1010 readback_request.GetResultCallback());
1011 readbacks_waiting_for_frame_.pop();
1012 }
1013 }
968 } 1014 }
969 1015
970 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame( 1016 void RenderWidgetHostViewAndroid::OnSwapCompositorFrame(
971 uint32 output_surface_id, 1017 uint32 output_surface_id,
972 scoped_ptr<cc::CompositorFrame> frame) { 1018 scoped_ptr<cc::CompositorFrame> frame) {
973 InternalSwapCompositorFrame(output_surface_id, frame.Pass()); 1019 InternalSwapCompositorFrame(output_surface_id, frame.Pass());
974 } 1020 }
975 1021
976 void RenderWidgetHostViewAndroid::RetainFrame( 1022 void RenderWidgetHostViewAndroid::RetainFrame(
977 uint32 output_surface_id, 1023 uint32 output_surface_id,
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 } 1229 }
1184 1230
1185 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() { 1231 void RenderWidgetHostViewAndroid::AcceleratedSurfaceRelease() {
1186 NOTREACHED(); 1232 NOTREACHED();
1187 } 1233 }
1188 1234
1189 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() { 1235 void RenderWidgetHostViewAndroid::EvictDelegatedFrame() {
1190 if (layer_.get()) 1236 if (layer_.get())
1191 DestroyDelegatedContent(); 1237 DestroyDelegatedContent();
1192 frame_evictor_->DiscardedFrame(); 1238 frame_evictor_->DiscardedFrame();
1239 // We are evicting the delegated frame,
1240 // so there should be no pending readback requests
1241 DCHECK(readbacks_waiting_for_frame_.empty());
1193 } 1242 }
1194 1243
1195 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface( 1244 bool RenderWidgetHostViewAndroid::HasAcceleratedSurface(
1196 const gfx::Size& desired_size) { 1245 const gfx::Size& desired_size) {
1197 NOTREACHED(); 1246 NOTREACHED();
1198 return false; 1247 return false;
1199 } 1248 }
1200 1249
1201 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) { 1250 void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) {
1202 // ScreenInfo isn't tied to the widget on Android. Always return the default. 1251 // ScreenInfo isn't tied to the widget on Android. Always return the default.
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) { 1560 void RenderWidgetHostViewAndroid::OnAnimate(base::TimeTicks begin_frame_time) {
1512 if (Animate(begin_frame_time)) 1561 if (Animate(begin_frame_time))
1513 SetNeedsAnimate(); 1562 SetNeedsAnimate();
1514 } 1563 }
1515 1564
1516 void RenderWidgetHostViewAndroid::OnLostResources() { 1565 void RenderWidgetHostViewAndroid::OnLostResources() {
1517 ReleaseLocksOnSurface(); 1566 ReleaseLocksOnSurface();
1518 if (layer_.get()) 1567 if (layer_.get())
1519 DestroyDelegatedContent(); 1568 DestroyDelegatedContent();
1520 DCHECK(ack_callbacks_.empty()); 1569 DCHECK(ack_callbacks_.empty());
1570 // We should not loose a frame if we have readback requests pending.
1571 DCHECK(readbacks_waiting_for_frame_.empty());
1521 } 1572 }
1522 1573
1523 // static 1574 // static
1524 void 1575 void
1525 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback( 1576 RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResultForDelegatedReadback(
1526 const gfx::Size& dst_size_in_pixel, 1577 const gfx::Size& dst_size_in_pixel,
1527 const SkColorType color_type, 1578 const SkColorType color_type,
1528 const base::TimeTicks& start_time, 1579 const base::TimeTicks& start_time,
1529 scoped_refptr<cc::Layer> readback_layer, 1580 scoped_refptr<cc::Layer> readback_layer,
1530 const base::Callback<void(bool, const SkBitmap&)>& callback, 1581 const base::Callback<void(bool, const SkBitmap&)>& callback,
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 results->orientationAngle = display.RotationAsDegree(); 1701 results->orientationAngle = display.RotationAsDegree();
1651 results->orientationType = 1702 results->orientationType =
1652 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display); 1703 RenderWidgetHostViewBase::GetOrientationTypeForMobile(display);
1653 gfx::DeviceDisplayInfo info; 1704 gfx::DeviceDisplayInfo info;
1654 results->depth = info.GetBitsPerPixel(); 1705 results->depth = info.GetBitsPerPixel();
1655 results->depthPerComponent = info.GetBitsPerComponent(); 1706 results->depthPerComponent = info.GetBitsPerComponent();
1656 results->isMonochrome = (results->depthPerComponent == 0); 1707 results->isMonochrome = (results->depthPerComponent == 0);
1657 } 1708 }
1658 1709
1659 } // namespace content 1710 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698