| 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 |