| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "android_webview/browser/browser_view_renderer.h" | 5 #include "android_webview/browser/browser_view_renderer.h" |
| 6 | 6 |
| 7 #include "android_webview/browser/browser_view_renderer_client.h" | 7 #include "android_webview/browser/browser_view_renderer_client.h" |
| 8 #include "android_webview/browser/child_frame.h" | 8 #include "android_webview/browser/child_frame.h" |
| 9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 #include "third_party/skia/include/core/SkPictureRecorder.h" | 23 #include "third_party/skia/include/core/SkPictureRecorder.h" |
| 24 #include "ui/gfx/geometry/scroll_offset.h" | 24 #include "ui/gfx/geometry/scroll_offset.h" |
| 25 #include "ui/gfx/geometry/vector2d_conversions.h" | 25 #include "ui/gfx/geometry/vector2d_conversions.h" |
| 26 | 26 |
| 27 namespace android_webview { | 27 namespace android_webview { |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 const double kEpsilon = 1e-8; | 31 const double kEpsilon = 1e-8; |
| 32 | 32 |
| 33 const int64 kFallbackTickTimeoutInMilliseconds = 100; |
| 34 |
| 33 // Used to calculate memory allocation. Determined experimentally. | 35 // Used to calculate memory allocation. Determined experimentally. |
| 34 const size_t kMemoryMultiplier = 20; | 36 const size_t kMemoryMultiplier = 20; |
| 35 const size_t kBytesPerPixel = 4; | 37 const size_t kBytesPerPixel = 4; |
| 36 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; | 38 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; |
| 37 uint64_t g_memory_override_in_bytes = 0u; | 39 uint64_t g_memory_override_in_bytes = 0u; |
| 38 | 40 |
| 39 const void* const kBrowserViewRendererUserDataKey = | 41 const void* const kBrowserViewRendererUserDataKey = |
| 40 &kBrowserViewRendererUserDataKey; | 42 &kBrowserViewRendererUserDataKey; |
| 41 | 43 |
| 42 class BrowserViewRendererUserData : public base::SupportsUserData::Data { | 44 class BrowserViewRendererUserData : public base::SupportsUserData::Data { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 view_visible_(false), | 96 view_visible_(false), |
| 95 window_visible_(false), | 97 window_visible_(false), |
| 96 attached_to_window_(false), | 98 attached_to_window_(false), |
| 97 hardware_enabled_(false), | 99 hardware_enabled_(false), |
| 98 dip_scale_(0.f), | 100 dip_scale_(0.f), |
| 99 page_scale_factor_(1.f), | 101 page_scale_factor_(1.f), |
| 100 min_page_scale_factor_(0.f), | 102 min_page_scale_factor_(0.f), |
| 101 max_page_scale_factor_(0.f), | 103 max_page_scale_factor_(0.f), |
| 102 on_new_picture_enable_(false), | 104 on_new_picture_enable_(false), |
| 103 clear_view_(false), | 105 clear_view_(false), |
| 104 offscreen_pre_raster_(false) {} | 106 offscreen_pre_raster_(false), |
| 107 fallback_tick_pending_(false) {} |
| 105 | 108 |
| 106 BrowserViewRenderer::~BrowserViewRenderer() { | 109 BrowserViewRenderer::~BrowserViewRenderer() { |
| 107 } | 110 } |
| 108 | 111 |
| 109 void BrowserViewRenderer::RegisterWithWebContents( | 112 void BrowserViewRenderer::RegisterWithWebContents( |
| 110 content::WebContents* web_contents) { | 113 content::WebContents* web_contents) { |
| 111 web_contents->SetUserData(kBrowserViewRendererUserDataKey, | 114 web_contents->SetUserData(kBrowserViewRendererUserDataKey, |
| 112 new BrowserViewRendererUserData(this)); | 115 new BrowserViewRendererUserData(this)); |
| 113 } | 116 } |
| 114 | 117 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 218 |
| 216 shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); | 219 shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); |
| 217 | 220 |
| 218 if (!CanOnDraw()) { | 221 if (!CanOnDraw()) { |
| 219 return false; | 222 return false; |
| 220 } | 223 } |
| 221 | 224 |
| 222 shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_); | 225 shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_); |
| 223 hardware_enabled_ = true; | 226 hardware_enabled_ = true; |
| 224 | 227 |
| 228 return CompositeHw(); |
| 229 } |
| 230 |
| 231 bool BrowserViewRenderer::CompositeHw() { |
| 232 CancelFallbackTick(); |
| 233 |
| 225 ReturnResourceFromParent(); | 234 ReturnResourceFromParent(); |
| 226 UpdateMemoryPolicy(); | 235 UpdateMemoryPolicy(); |
| 227 | 236 |
| 228 ParentCompositorDrawConstraints parent_draw_constraints = | 237 ParentCompositorDrawConstraints parent_draw_constraints = |
| 229 shared_renderer_state_.GetParentDrawConstraintsOnUI(); | 238 shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
| 230 gfx::Size surface_size(size_); | 239 gfx::Size surface_size(size_); |
| 231 gfx::Rect viewport(surface_size); | 240 gfx::Rect viewport(surface_size); |
| 232 gfx::Rect clip = viewport; | 241 gfx::Rect clip = viewport; |
| 233 gfx::Transform transform_for_tile_priority = | 242 gfx::Transform transform_for_tile_priority = |
| 234 parent_draw_constraints.transform; | 243 parent_draw_constraints.transform; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 254 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 263 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
| 255 TRACE_EVENT_SCOPE_THREAD); | 264 TRACE_EVENT_SCOPE_THREAD); |
| 256 return shared_renderer_state_.HasFrameOnUI(); | 265 return shared_renderer_state_.HasFrameOnUI(); |
| 257 } | 266 } |
| 258 | 267 |
| 259 scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( | 268 scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( |
| 260 new ChildFrame(frame.Pass(), viewport_rect_for_tile_priority.IsEmpty(), | 269 new ChildFrame(frame.Pass(), viewport_rect_for_tile_priority.IsEmpty(), |
| 261 transform_for_tile_priority, offscreen_pre_raster_, | 270 transform_for_tile_priority, offscreen_pre_raster_, |
| 262 parent_draw_constraints.is_layer)); | 271 parent_draw_constraints.is_layer)); |
| 263 | 272 |
| 264 // If we haven't received a kModeSync functor call since the last | 273 // Uncommitted frame can happen with consecutive fallback ticks. |
| 265 // CompositeHw then we need to discard the resources that are being | |
| 266 // held onto by the previously prepared frame. | |
| 267 ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); | 274 ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); |
| 268 shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); | 275 shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); |
| 269 return true; | 276 return true; |
| 270 } | 277 } |
| 271 | 278 |
| 272 void BrowserViewRenderer::UpdateParentDrawConstraints() { | 279 void BrowserViewRenderer::UpdateParentDrawConstraints() { |
| 273 PostInvalidate(); | 280 PostInvalidateWithFallback(); |
| 274 ParentCompositorDrawConstraints parent_draw_constraints = | 281 ParentCompositorDrawConstraints parent_draw_constraints = |
| 275 shared_renderer_state_.GetParentDrawConstraintsOnUI(); | 282 shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
| 276 client_->ParentDrawConstraintsUpdated(parent_draw_constraints); | 283 client_->ParentDrawConstraintsUpdated(parent_draw_constraints); |
| 277 } | 284 } |
| 278 | 285 |
| 279 void BrowserViewRenderer::ReturnUnusedResource( | 286 void BrowserViewRenderer::ReturnUnusedResource( |
| 280 scoped_ptr<ChildFrame> child_frame) { | 287 scoped_ptr<ChildFrame> child_frame) { |
| 281 if (!child_frame.get() || !child_frame->frame.get()) | 288 if (!child_frame.get() || !child_frame->frame.get()) |
| 282 return; | 289 return; |
| 283 | 290 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 | 344 |
| 338 void BrowserViewRenderer::ClearView() { | 345 void BrowserViewRenderer::ClearView() { |
| 339 TRACE_EVENT_INSTANT0("android_webview", | 346 TRACE_EVENT_INSTANT0("android_webview", |
| 340 "BrowserViewRenderer::ClearView", | 347 "BrowserViewRenderer::ClearView", |
| 341 TRACE_EVENT_SCOPE_THREAD); | 348 TRACE_EVENT_SCOPE_THREAD); |
| 342 if (clear_view_) | 349 if (clear_view_) |
| 343 return; | 350 return; |
| 344 | 351 |
| 345 clear_view_ = true; | 352 clear_view_ = true; |
| 346 // Always invalidate ignoring the compositor to actually clear the webview. | 353 // Always invalidate ignoring the compositor to actually clear the webview. |
| 347 PostInvalidate(); | 354 PostInvalidateWithFallback(); |
| 348 } | 355 } |
| 349 | 356 |
| 350 void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { | 357 void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { |
| 351 if (offscreen_pre_raster_ != enable && compositor_) | 358 if (offscreen_pre_raster_ != enable && compositor_) |
| 352 UpdateMemoryPolicy(); | 359 UpdateMemoryPolicy(); |
| 353 | 360 |
| 354 offscreen_pre_raster_ = enable; | 361 offscreen_pre_raster_ = enable; |
| 355 } | 362 } |
| 356 | 363 |
| 357 void BrowserViewRenderer::SetIsPaused(bool paused) { | 364 void BrowserViewRenderer::SetIsPaused(bool paused) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 scaled_overscroll_delta - rounded_overscroll_delta; | 642 scaled_overscroll_delta - rounded_overscroll_delta; |
| 636 gfx::Vector2dF fling_velocity_pixels = | 643 gfx::Vector2dF fling_velocity_pixels = |
| 637 gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale); | 644 gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale); |
| 638 | 645 |
| 639 client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels); | 646 client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels); |
| 640 } | 647 } |
| 641 | 648 |
| 642 void BrowserViewRenderer::PostInvalidate() { | 649 void BrowserViewRenderer::PostInvalidate() { |
| 643 TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", | 650 TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", |
| 644 TRACE_EVENT_SCOPE_THREAD); | 651 TRACE_EVENT_SCOPE_THREAD); |
| 652 PostInvalidateWithFallback(); |
| 653 } |
| 654 |
| 655 void BrowserViewRenderer::PostInvalidateWithFallback() { |
| 656 // Always call view invalidate. We rely the Android framework to ignore the |
| 657 // invalidate when it's not needed such as when view is not visible. |
| 645 client_->PostInvalidate(); | 658 client_->PostInvalidate(); |
| 659 |
| 660 // Stop fallback ticks when one of these is true. |
| 661 // 1) Webview is paused. Also need to check we are not in clear view since |
| 662 // paused, offscreen still expect clear view to recover. |
| 663 // 2) If we are attached to window and the window is not visible (eg when |
| 664 // app is in the background). We are sure in this case the webview is used |
| 665 // "on-screen" but that updates are not needed when in the background. |
| 666 bool throttle_fallback_tick = |
| 667 (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_); |
| 668 |
| 669 if (throttle_fallback_tick || fallback_tick_pending_) |
| 670 return; |
| 671 |
| 672 DCHECK(post_fallback_tick_.IsCancelled()); |
| 673 DCHECK(fallback_tick_fired_.IsCancelled()); |
| 674 |
| 675 post_fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::PostFallbackTick, |
| 676 base::Unretained(this))); |
| 677 ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback()); |
| 678 fallback_tick_pending_ = true; |
| 679 } |
| 680 |
| 681 void BrowserViewRenderer::CancelFallbackTick() { |
| 682 post_fallback_tick_.Cancel(); |
| 683 fallback_tick_fired_.Cancel(); |
| 684 fallback_tick_pending_ = false; |
| 685 } |
| 686 |
| 687 void BrowserViewRenderer::PostFallbackTick() { |
| 688 DCHECK(fallback_tick_fired_.IsCancelled()); |
| 689 TRACE_EVENT0("android_webview", "BrowserViewRenderer::PostFallbackTick"); |
| 690 post_fallback_tick_.Cancel(); |
| 691 fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired, |
| 692 base::Unretained(this))); |
| 693 ui_task_runner_->PostDelayedTask( |
| 694 FROM_HERE, fallback_tick_fired_.callback(), |
| 695 base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |
| 696 } |
| 697 |
| 698 void BrowserViewRenderer::FallbackTickFired() { |
| 699 TRACE_EVENT0("android_webview", "BrowserViewRenderer::FallbackTickFired"); |
| 700 // This should only be called if OnDraw or DrawGL did not come in time, which |
| 701 // means fallback_tick_pending_ must still be true. |
| 702 DCHECK(fallback_tick_pending_); |
| 703 fallback_tick_fired_.Cancel(); |
| 704 fallback_tick_pending_ = false; |
| 705 if (compositor_) { |
| 706 if (hardware_enabled_ && !size_.IsEmpty()) { |
| 707 CompositeHw(); |
| 708 } else { |
| 709 ForceFakeCompositeSW(); |
| 710 } |
| 711 } |
| 712 } |
| 713 |
| 714 void BrowserViewRenderer::ForceFakeCompositeSW() { |
| 715 DCHECK(compositor_); |
| 716 SkBitmap bitmap; |
| 717 bitmap.allocN32Pixels(1, 1); |
| 718 bitmap.eraseColor(0); |
| 719 SkCanvas canvas(bitmap); |
| 720 CompositeSW(&canvas); |
| 646 } | 721 } |
| 647 | 722 |
| 648 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { | 723 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { |
| 649 DCHECK(compositor_); | 724 DCHECK(compositor_); |
| 725 CancelFallbackTick(); |
| 650 ReturnResourceFromParent(); | 726 ReturnResourceFromParent(); |
| 651 return compositor_->DemandDrawSw(canvas); | 727 return compositor_->DemandDrawSw(canvas); |
| 652 } | 728 } |
| 653 | 729 |
| 654 void BrowserViewRenderer::UpdateCompositorIsActive() { | 730 void BrowserViewRenderer::UpdateCompositorIsActive() { |
| 655 if (compositor_) { | 731 if (compositor_) { |
| 656 if (disable_page_visibility_) | 732 if (disable_page_visibility_) |
| 657 compositor_->SetIsActive(!is_paused_ && | 733 compositor_->SetIsActive(!is_paused_ && |
| 658 (!attached_to_window_ || window_visible_)); | 734 (!attached_to_window_ || window_visible_)); |
| 659 else | 735 else |
| 660 compositor_->SetIsActive(IsClientVisible()); | 736 compositor_->SetIsActive(IsClientVisible()); |
| 661 } | 737 } |
| 662 } | 738 } |
| 663 | 739 |
| 664 std::string BrowserViewRenderer::ToString() const { | 740 std::string BrowserViewRenderer::ToString() const { |
| 665 std::string str; | 741 std::string str; |
| 666 base::StringAppendF(&str, "is_paused: %d ", is_paused_); | 742 base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
| 667 base::StringAppendF(&str, "view_visible: %d ", view_visible_); | 743 base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
| 668 base::StringAppendF(&str, "window_visible: %d ", window_visible_); | 744 base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
| 669 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 745 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
| 670 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 746 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
| 747 base::StringAppendF(&str, "fallback_tick_pending: %d ", |
| 748 fallback_tick_pending_); |
| 671 base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); | 749 base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); |
| 672 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); | 750 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
| 673 base::StringAppendF(&str, | 751 base::StringAppendF(&str, |
| 674 "global visible rect: %s ", | 752 "global visible rect: %s ", |
| 675 last_on_draw_global_visible_rect_.ToString().c_str()); | 753 last_on_draw_global_visible_rect_.ToString().c_str()); |
| 676 base::StringAppendF( | 754 base::StringAppendF( |
| 677 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); | 755 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); |
| 678 base::StringAppendF(&str, | 756 base::StringAppendF(&str, |
| 679 "overscroll_rounding_error_: %s ", | 757 "overscroll_rounding_error_: %s ", |
| 680 overscroll_rounding_error_.ToString().c_str()); | 758 overscroll_rounding_error_.ToString().c_str()); |
| 681 base::StringAppendF( | 759 base::StringAppendF( |
| 682 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 760 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 683 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 761 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
| 684 return str; | 762 return str; |
| 685 } | 763 } |
| 686 | 764 |
| 687 } // namespace android_webview | 765 } // namespace android_webview |
| OLD | NEW |