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 | |
35 // Used to calculate memory allocation. Determined experimentally. | 33 // Used to calculate memory allocation. Determined experimentally. |
36 const size_t kMemoryMultiplier = 20; | 34 const size_t kMemoryMultiplier = 20; |
37 const size_t kBytesPerPixel = 4; | 35 const size_t kBytesPerPixel = 4; |
38 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; | 36 const size_t kMemoryAllocationStep = 5 * 1024 * 1024; |
39 uint64_t g_memory_override_in_bytes = 0u; | 37 uint64_t g_memory_override_in_bytes = 0u; |
40 | 38 |
41 const void* const kBrowserViewRendererUserDataKey = | 39 const void* const kBrowserViewRendererUserDataKey = |
42 &kBrowserViewRendererUserDataKey; | 40 &kBrowserViewRendererUserDataKey; |
43 | 41 |
44 class BrowserViewRendererUserData : public base::SupportsUserData::Data { | 42 class BrowserViewRendererUserData : public base::SupportsUserData::Data { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 view_visible_(false), | 94 view_visible_(false), |
97 window_visible_(false), | 95 window_visible_(false), |
98 attached_to_window_(false), | 96 attached_to_window_(false), |
99 hardware_enabled_(false), | 97 hardware_enabled_(false), |
100 dip_scale_(0.f), | 98 dip_scale_(0.f), |
101 page_scale_factor_(1.f), | 99 page_scale_factor_(1.f), |
102 min_page_scale_factor_(0.f), | 100 min_page_scale_factor_(0.f), |
103 max_page_scale_factor_(0.f), | 101 max_page_scale_factor_(0.f), |
104 on_new_picture_enable_(false), | 102 on_new_picture_enable_(false), |
105 clear_view_(false), | 103 clear_view_(false), |
106 offscreen_pre_raster_(false), | 104 offscreen_pre_raster_(false) {} |
107 fallback_tick_pending_(false) {} | |
108 | 105 |
109 BrowserViewRenderer::~BrowserViewRenderer() { | 106 BrowserViewRenderer::~BrowserViewRenderer() { |
110 } | 107 } |
111 | 108 |
112 void BrowserViewRenderer::RegisterWithWebContents( | 109 void BrowserViewRenderer::RegisterWithWebContents( |
113 content::WebContents* web_contents) { | 110 content::WebContents* web_contents) { |
114 web_contents->SetUserData(kBrowserViewRendererUserDataKey, | 111 web_contents->SetUserData(kBrowserViewRendererUserDataKey, |
115 new BrowserViewRendererUserData(this)); | 112 new BrowserViewRendererUserData(this)); |
116 } | 113 } |
117 | 114 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 215 |
219 shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); | 216 shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); |
220 | 217 |
221 if (!CanOnDraw()) { | 218 if (!CanOnDraw()) { |
222 return false; | 219 return false; |
223 } | 220 } |
224 | 221 |
225 shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_); | 222 shared_renderer_state_.SetScrollOffsetOnUI(last_on_draw_scroll_offset_); |
226 hardware_enabled_ = true; | 223 hardware_enabled_ = true; |
227 | 224 |
228 return CompositeHw(); | |
229 } | |
230 | |
231 bool BrowserViewRenderer::CompositeHw() { | |
232 CancelFallbackTick(); | |
233 | |
234 ReturnResourceFromParent(); | 225 ReturnResourceFromParent(); |
235 UpdateMemoryPolicy(); | 226 UpdateMemoryPolicy(); |
236 | 227 |
237 ParentCompositorDrawConstraints parent_draw_constraints = | 228 ParentCompositorDrawConstraints parent_draw_constraints = |
238 shared_renderer_state_.GetParentDrawConstraintsOnUI(); | 229 shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
239 gfx::Size surface_size(size_); | 230 gfx::Size surface_size(size_); |
240 gfx::Rect viewport(surface_size); | 231 gfx::Rect viewport(surface_size); |
241 gfx::Rect clip = viewport; | 232 gfx::Rect clip = viewport; |
242 gfx::Transform transform_for_tile_priority = | 233 gfx::Transform transform_for_tile_priority = |
243 parent_draw_constraints.transform; | 234 parent_draw_constraints.transform; |
(...skipping 19 matching lines...) Expand all Loading... |
263 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", | 254 TRACE_EVENT_INSTANT0("android_webview", "NoNewFrame", |
264 TRACE_EVENT_SCOPE_THREAD); | 255 TRACE_EVENT_SCOPE_THREAD); |
265 return shared_renderer_state_.HasFrameOnUI(); | 256 return shared_renderer_state_.HasFrameOnUI(); |
266 } | 257 } |
267 | 258 |
268 scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( | 259 scoped_ptr<ChildFrame> child_frame = make_scoped_ptr( |
269 new ChildFrame(frame.Pass(), viewport_rect_for_tile_priority.IsEmpty(), | 260 new ChildFrame(frame.Pass(), viewport_rect_for_tile_priority.IsEmpty(), |
270 transform_for_tile_priority, offscreen_pre_raster_, | 261 transform_for_tile_priority, offscreen_pre_raster_, |
271 parent_draw_constraints.is_layer)); | 262 parent_draw_constraints.is_layer)); |
272 | 263 |
273 // Uncommitted frame can happen with consecutive fallback ticks. | 264 // If we haven't received a kModeSync functor call since the last |
| 265 // CompositeHw then we need to discard the resources that are being |
| 266 // held onto by the previously prepared frame. |
274 ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); | 267 ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); |
275 shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); | 268 shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); |
276 return true; | 269 return true; |
277 } | 270 } |
278 | 271 |
279 void BrowserViewRenderer::UpdateParentDrawConstraints() { | 272 void BrowserViewRenderer::UpdateParentDrawConstraints() { |
280 PostInvalidateWithFallback(); | 273 PostInvalidate(); |
281 ParentCompositorDrawConstraints parent_draw_constraints = | 274 ParentCompositorDrawConstraints parent_draw_constraints = |
282 shared_renderer_state_.GetParentDrawConstraintsOnUI(); | 275 shared_renderer_state_.GetParentDrawConstraintsOnUI(); |
283 client_->ParentDrawConstraintsUpdated(parent_draw_constraints); | 276 client_->ParentDrawConstraintsUpdated(parent_draw_constraints); |
284 } | 277 } |
285 | 278 |
286 void BrowserViewRenderer::ReturnUnusedResource( | 279 void BrowserViewRenderer::ReturnUnusedResource( |
287 scoped_ptr<ChildFrame> child_frame) { | 280 scoped_ptr<ChildFrame> child_frame) { |
288 if (!child_frame.get() || !child_frame->frame.get()) | 281 if (!child_frame.get() || !child_frame->frame.get()) |
289 return; | 282 return; |
290 | 283 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 | 337 |
345 void BrowserViewRenderer::ClearView() { | 338 void BrowserViewRenderer::ClearView() { |
346 TRACE_EVENT_INSTANT0("android_webview", | 339 TRACE_EVENT_INSTANT0("android_webview", |
347 "BrowserViewRenderer::ClearView", | 340 "BrowserViewRenderer::ClearView", |
348 TRACE_EVENT_SCOPE_THREAD); | 341 TRACE_EVENT_SCOPE_THREAD); |
349 if (clear_view_) | 342 if (clear_view_) |
350 return; | 343 return; |
351 | 344 |
352 clear_view_ = true; | 345 clear_view_ = true; |
353 // Always invalidate ignoring the compositor to actually clear the webview. | 346 // Always invalidate ignoring the compositor to actually clear the webview. |
354 PostInvalidateWithFallback(); | 347 PostInvalidate(); |
355 } | 348 } |
356 | 349 |
357 void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { | 350 void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { |
358 if (offscreen_pre_raster_ != enable && compositor_) | 351 if (offscreen_pre_raster_ != enable && compositor_) |
359 UpdateMemoryPolicy(); | 352 UpdateMemoryPolicy(); |
360 | 353 |
361 offscreen_pre_raster_ = enable; | 354 offscreen_pre_raster_ = enable; |
362 } | 355 } |
363 | 356 |
364 void BrowserViewRenderer::SetIsPaused(bool paused) { | 357 void BrowserViewRenderer::SetIsPaused(bool paused) { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 scaled_overscroll_delta - rounded_overscroll_delta; | 635 scaled_overscroll_delta - rounded_overscroll_delta; |
643 gfx::Vector2dF fling_velocity_pixels = | 636 gfx::Vector2dF fling_velocity_pixels = |
644 gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale); | 637 gfx::ScaleVector2d(current_fling_velocity, physical_pixel_scale); |
645 | 638 |
646 client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels); | 639 client_->DidOverscroll(rounded_overscroll_delta, fling_velocity_pixels); |
647 } | 640 } |
648 | 641 |
649 void BrowserViewRenderer::PostInvalidate() { | 642 void BrowserViewRenderer::PostInvalidate() { |
650 TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", | 643 TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", |
651 TRACE_EVENT_SCOPE_THREAD); | 644 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. | |
658 client_->PostInvalidate(); | 645 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); | |
721 } | 646 } |
722 | 647 |
723 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { | 648 bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { |
724 DCHECK(compositor_); | 649 DCHECK(compositor_); |
725 CancelFallbackTick(); | |
726 ReturnResourceFromParent(); | 650 ReturnResourceFromParent(); |
727 return compositor_->DemandDrawSw(canvas); | 651 return compositor_->DemandDrawSw(canvas); |
728 } | 652 } |
729 | 653 |
730 void BrowserViewRenderer::UpdateCompositorIsActive() { | 654 void BrowserViewRenderer::UpdateCompositorIsActive() { |
731 if (compositor_) { | 655 if (compositor_) { |
732 if (disable_page_visibility_) | 656 if (disable_page_visibility_) |
733 compositor_->SetIsActive(!is_paused_ && | 657 compositor_->SetIsActive(!is_paused_ && |
734 (!attached_to_window_ || window_visible_)); | 658 (!attached_to_window_ || window_visible_)); |
735 else | 659 else |
736 compositor_->SetIsActive(IsClientVisible()); | 660 compositor_->SetIsActive(IsClientVisible()); |
737 } | 661 } |
738 } | 662 } |
739 | 663 |
740 std::string BrowserViewRenderer::ToString() const { | 664 std::string BrowserViewRenderer::ToString() const { |
741 std::string str; | 665 std::string str; |
742 base::StringAppendF(&str, "is_paused: %d ", is_paused_); | 666 base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
743 base::StringAppendF(&str, "view_visible: %d ", view_visible_); | 667 base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
744 base::StringAppendF(&str, "window_visible: %d ", window_visible_); | 668 base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
745 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 669 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
746 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 670 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
747 base::StringAppendF(&str, "fallback_tick_pending: %d ", | |
748 fallback_tick_pending_); | |
749 base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); | 671 base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); |
750 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); | 672 base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
751 base::StringAppendF(&str, | 673 base::StringAppendF(&str, |
752 "global visible rect: %s ", | 674 "global visible rect: %s ", |
753 last_on_draw_global_visible_rect_.ToString().c_str()); | 675 last_on_draw_global_visible_rect_.ToString().c_str()); |
754 base::StringAppendF( | 676 base::StringAppendF( |
755 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); | 677 &str, "scroll_offset_dip: %s ", scroll_offset_dip_.ToString().c_str()); |
756 base::StringAppendF(&str, | 678 base::StringAppendF(&str, |
757 "overscroll_rounding_error_: %s ", | 679 "overscroll_rounding_error_: %s ", |
758 overscroll_rounding_error_.ToString().c_str()); | 680 overscroll_rounding_error_.ToString().c_str()); |
759 base::StringAppendF( | 681 base::StringAppendF( |
760 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 682 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
761 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 683 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
762 return str; | 684 return str; |
763 } | 685 } |
764 | 686 |
765 } // namespace android_webview | 687 } // namespace android_webview |
OLD | NEW |