Chromium Code Reviews| 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/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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |