OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |