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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |