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