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 |