| 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/shared_renderer_state.h" | 8 #include "android_webview/browser/shared_renderer_state.h" |
| 9 #include "android_webview/common/aw_switches.h" | 9 #include "android_webview/common/aw_switches.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 is_paused_(false), | 78 is_paused_(false), |
| 79 view_visible_(false), | 79 view_visible_(false), |
| 80 window_visible_(false), | 80 window_visible_(false), |
| 81 attached_to_window_(false), | 81 attached_to_window_(false), |
| 82 hardware_enabled_(false), | 82 hardware_enabled_(false), |
| 83 dip_scale_(0.0), | 83 dip_scale_(0.0), |
| 84 page_scale_factor_(1.0), | 84 page_scale_factor_(1.0), |
| 85 on_new_picture_enable_(false), | 85 on_new_picture_enable_(false), |
| 86 clear_view_(false), | 86 clear_view_(false), |
| 87 compositor_needs_continuous_invalidate_(false), | 87 compositor_needs_continuous_invalidate_(false), |
| 88 invalidate_after_composite_(false), |
| 88 block_invalidates_(false), | 89 block_invalidates_(false), |
| 89 fallback_tick_pending_(false), | 90 fallback_tick_pending_(false), |
| 90 width_(0), | 91 width_(0), |
| 91 height_(0) { | 92 height_(0) { |
| 92 CHECK(web_contents_); | 93 CHECK(web_contents_); |
| 93 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); | 94 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); |
| 94 | 95 |
| 95 // Currently the logic in this class relies on |compositor_| remaining | 96 // Currently the logic in this class relies on |compositor_| remaining |
| 96 // NULL until the DidInitializeCompositor() call, hence it is not set here. | 97 // NULL until the DidInitializeCompositor() call, hence it is not set here. |
| 97 } | 98 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 // Perform a software draw | 205 // Perform a software draw |
| 205 return OnDrawSoftware(java_canvas); | 206 return OnDrawSoftware(java_canvas); |
| 206 } | 207 } |
| 207 | 208 |
| 208 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { | 209 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { |
| 209 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); | 210 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); |
| 210 if (!compositor_) | 211 if (!compositor_) |
| 211 return false; | 212 return false; |
| 212 | 213 |
| 213 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); | 214 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); |
| 214 if (last_on_draw_global_visible_rect_.IsEmpty()) { | |
| 215 TRACE_EVENT_INSTANT0("android_webview", | |
| 216 "EarlyOut_EmptyVisibleRect", | |
| 217 TRACE_EVENT_SCOPE_THREAD); | |
| 218 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); | |
| 219 return client_->RequestDrawGL(java_canvas, false); | |
| 220 } | |
| 221 | 215 |
| 222 if (!hardware_enabled_) { | 216 if (!hardware_enabled_) { |
| 223 hardware_enabled_ = compositor_->InitializeHwDraw(); | 217 hardware_enabled_ = compositor_->InitializeHwDraw(); |
| 224 if (hardware_enabled_) { | 218 if (hardware_enabled_) { |
| 225 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); | 219 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); |
| 226 } | 220 } |
| 227 } | 221 } |
| 228 if (!hardware_enabled_) | 222 if (!hardware_enabled_) |
| 229 return false; | 223 return false; |
| 230 | 224 |
| 225 if (last_on_draw_global_visible_rect_.IsEmpty() && |
| 226 parent_draw_constraints_.surface_rect.IsEmpty()) { |
| 227 TRACE_EVENT_INSTANT0("android_webview", |
| 228 "EarlyOut_EmptyVisibleRect", |
| 229 TRACE_EVENT_SCOPE_THREAD); |
| 230 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); |
| 231 return client_->RequestDrawGL(java_canvas, false); |
| 232 } |
| 233 |
| 231 ReturnResourceFromParent(); | 234 ReturnResourceFromParent(); |
| 232 if (shared_renderer_state_->HasCompositorFrame()) { | 235 if (shared_renderer_state_->HasCompositorFrame()) { |
| 233 TRACE_EVENT_INSTANT0("android_webview", | 236 TRACE_EVENT_INSTANT0("android_webview", |
| 234 "EarlyOut_PreviousFrameUnconsumed", | 237 "EarlyOut_PreviousFrameUnconsumed", |
| 235 TRACE_EVENT_SCOPE_THREAD); | 238 TRACE_EVENT_SCOPE_THREAD); |
| 236 SkippedCompositeInDraw(); | 239 DidSkipCompositeInDraw(); |
| 237 return client_->RequestDrawGL(java_canvas, false); | 240 return client_->RequestDrawGL(java_canvas, false); |
| 238 } | 241 } |
| 239 | 242 |
| 240 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); | 243 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); |
| 241 if (!frame.get()) | 244 if (!frame.get()) |
| 242 return false; | 245 return false; |
| 243 | 246 |
| 244 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); | 247 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); |
| 245 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); | 248 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); |
| 246 return client_->RequestDrawGL(java_canvas, false); | 249 return client_->RequestDrawGL(java_canvas, false); |
| 247 } | 250 } |
| 248 | 251 |
| 249 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { | 252 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { |
| 250 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); | 253 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); |
| 251 RequestMemoryPolicy(new_policy); | 254 RequestMemoryPolicy(new_policy); |
| 252 compositor_->SetMemoryPolicy(memory_policy_); | 255 compositor_->SetMemoryPolicy(memory_policy_); |
| 253 | 256 |
| 254 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); | 257 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); |
| 255 gfx::Size surface_size(width_, height_); | 258 gfx::Size surface_size(width_, height_); |
| 256 gfx::Rect viewport(surface_size); | 259 gfx::Rect viewport(surface_size); |
| 257 gfx::Rect clip = viewport; | 260 gfx::Rect clip = viewport; |
| 258 gfx::Transform transform_for_tile_priority = | 261 gfx::Transform transform_for_tile_priority = |
| 259 parent_draw_constraints_.transform; | 262 parent_draw_constraints_.transform; |
| 260 | 263 |
| 261 // If the WebView is on a layer, WebView does not know what transform is | 264 // If the WebView is on a layer, WebView does not know what transform is |
| 262 // applied onto the layer so global visible rect does not make sense here. | 265 // applied onto the layer so global visible rect does not make sense here. |
| 263 // In this case, just use the surface rect for tiling. | 266 // In this case, just use the surface rect for tiling. |
| 264 gfx::Rect viewport_rect_for_tile_priority; | 267 gfx::Rect viewport_rect_for_tile_priority; |
| 265 if (parent_draw_constraints_.is_layer) | 268 if (parent_draw_constraints_.is_layer || |
| 269 last_on_draw_global_visible_rect_.IsEmpty()) { |
| 266 viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; | 270 viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; |
| 267 else | 271 } else { |
| 268 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; | 272 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; |
| 273 } |
| 269 | 274 |
| 270 scoped_ptr<cc::CompositorFrame> frame = | 275 scoped_ptr<cc::CompositorFrame> frame = |
| 271 compositor_->DemandDrawHw(surface_size, | 276 compositor_->DemandDrawHw(surface_size, |
| 272 gfx::Transform(), | 277 gfx::Transform(), |
| 273 viewport, | 278 viewport, |
| 274 clip, | 279 clip, |
| 275 viewport_rect_for_tile_priority, | 280 viewport_rect_for_tile_priority, |
| 276 transform_for_tile_priority); | 281 transform_for_tile_priority); |
| 277 if (frame.get()) | 282 if (frame.get()) |
| 278 DidComposite(); | 283 DidComposite(); |
| 279 return frame.Pass(); | 284 return frame.Pass(); |
| 280 } | 285 } |
| 281 | 286 |
| 282 void BrowserViewRenderer::UpdateParentDrawConstraints() { | 287 void BrowserViewRenderer::UpdateParentDrawConstraints() { |
| 283 // Post an invalidate if the parent draw constraints are stale and there is | 288 // Post an invalidate if the parent draw constraints are stale and there is |
| 284 // no pending invalidate. | 289 // no pending invalidate. |
| 285 if (shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL() || | 290 bool needs_force_invalidate = |
| 291 shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL(); |
| 292 if (needs_force_invalidate || |
| 286 !parent_draw_constraints_.Equals( | 293 !parent_draw_constraints_.Equals( |
| 287 shared_renderer_state_->ParentDrawConstraints())) { | 294 shared_renderer_state_->ParentDrawConstraints())) { |
| 288 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(false); | 295 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(false); |
| 289 EnsureContinuousInvalidation(true, false); | 296 EnsureContinuousInvalidation(true, needs_force_invalidate); |
| 290 } | 297 } |
| 291 } | 298 } |
| 292 | 299 |
| 293 void BrowserViewRenderer::ReturnUnusedResource( | 300 void BrowserViewRenderer::ReturnUnusedResource( |
| 294 scoped_ptr<cc::CompositorFrame> frame) { | 301 scoped_ptr<cc::CompositorFrame> frame) { |
| 295 if (!frame.get()) | 302 if (!frame.get()) |
| 296 return; | 303 return; |
| 297 | 304 |
| 298 cc::CompositorFrameAck frame_ack; | 305 cc::CompositorFrameAck frame_ack; |
| 299 cc::TransferableResource::ReturnResources( | 306 cc::TransferableResource::ReturnResources( |
| 300 frame->delegated_frame_data->resource_list, &frame_ack.resources); | 307 frame->delegated_frame_data->resource_list, &frame_ack.resources); |
| 301 if (compositor_ && !frame_ack.resources.empty()) | 308 if (compositor_ && !frame_ack.resources.empty()) |
| 302 compositor_->ReturnResources(frame_ack); | 309 compositor_->ReturnResources(frame_ack); |
| 303 } | 310 } |
| 304 | 311 |
| 305 void BrowserViewRenderer::ReturnResourceFromParent() { | 312 void BrowserViewRenderer::ReturnResourceFromParent() { |
| 306 cc::CompositorFrameAck frame_ack; | 313 cc::CompositorFrameAck frame_ack; |
| 307 shared_renderer_state_->SwapReturnedResources(&frame_ack.resources); | 314 shared_renderer_state_->SwapReturnedResources(&frame_ack.resources); |
| 308 if (compositor_ && !frame_ack.resources.empty()) { | 315 if (compositor_ && !frame_ack.resources.empty()) { |
| 309 compositor_->ReturnResources(frame_ack); | 316 compositor_->ReturnResources(frame_ack); |
| 310 } | 317 } |
| 311 } | 318 } |
| 312 | 319 |
| 320 void BrowserViewRenderer::DidSkipCommitFrame() { |
| 321 // Treat it the same way as skipping onDraw. |
| 322 DidSkipCompositeInDraw(); |
| 323 } |
| 324 |
| 313 bool BrowserViewRenderer::OnDrawSoftware(jobject java_canvas) { | 325 bool BrowserViewRenderer::OnDrawSoftware(jobject java_canvas) { |
| 314 if (!compositor_) { | 326 if (!compositor_) { |
| 315 TRACE_EVENT_INSTANT0( | 327 TRACE_EVENT_INSTANT0( |
| 316 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); | 328 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); |
| 317 return false; | 329 return false; |
| 318 } | 330 } |
| 319 | 331 |
| 320 // TODO(hush): right now webview size is passed in as the auxiliary bitmap | 332 // TODO(hush): right now webview size is passed in as the auxiliary bitmap |
| 321 // size, which might hurt performace (only for software draws with auxiliary | 333 // size, which might hurt performace (only for software draws with auxiliary |
| 322 // bitmap). For better performance, get global visible rect, transform it | 334 // bitmap). For better performance, get global visible rect, transform it |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( | 661 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( |
| 650 scaled_overscroll_delta + overscroll_rounding_error_); | 662 scaled_overscroll_delta + overscroll_rounding_error_); |
| 651 overscroll_rounding_error_ = | 663 overscroll_rounding_error_ = |
| 652 scaled_overscroll_delta - rounded_overscroll_delta; | 664 scaled_overscroll_delta - rounded_overscroll_delta; |
| 653 client_->DidOverscroll(rounded_overscroll_delta); | 665 client_->DidOverscroll(rounded_overscroll_delta); |
| 654 } | 666 } |
| 655 | 667 |
| 656 void BrowserViewRenderer::EnsureContinuousInvalidation( | 668 void BrowserViewRenderer::EnsureContinuousInvalidation( |
| 657 bool force_invalidate, | 669 bool force_invalidate, |
| 658 bool skip_reschedule_tick) { | 670 bool skip_reschedule_tick) { |
| 671 if (force_invalidate) |
| 672 invalidate_after_composite_ = true; |
| 673 |
| 659 // This method should be called again when any of these conditions change. | 674 // This method should be called again when any of these conditions change. |
| 660 bool need_invalidate = | 675 bool need_invalidate = |
| 661 compositor_needs_continuous_invalidate_ || force_invalidate; | 676 compositor_needs_continuous_invalidate_ || invalidate_after_composite_; |
| 662 if (!need_invalidate || block_invalidates_) | 677 if (!need_invalidate || block_invalidates_) |
| 663 return; | 678 return; |
| 664 | 679 |
| 680 if (!compositor_needs_continuous_invalidate_ && invalidate_after_composite_) |
| 681 invalidate_after_composite_ = false; |
| 682 |
| 665 // Always call view invalidate. We rely the Android framework to ignore the | 683 // Always call view invalidate. We rely the Android framework to ignore the |
| 666 // invalidate when it's not needed such as when view is not visible. | 684 // invalidate when it's not needed such as when view is not visible. |
| 667 client_->PostInvalidate(); | 685 client_->PostInvalidate(); |
| 668 | 686 |
| 669 // Stop fallback ticks when one of these is true. | 687 // Stop fallback ticks when one of these is true. |
| 670 // 1) Webview is paused. Also need to check we are not in clear view since | 688 // 1) Webview is paused. Also need to check we are not in clear view since |
| 671 // paused, offscreen still expect clear view to recover. | 689 // paused, offscreen still expect clear view to recover. |
| 672 // 2) If we are attached to window and the window is not visible (eg when | 690 // 2) If we are attached to window and the window is not visible (eg when |
| 673 // app is in the background). We are sure in this case the webview is used | 691 // app is in the background). We are sure in this case the webview is used |
| 674 // "on-screen" but that updates are not needed when in the background. | 692 // "on-screen" but that updates are not needed when in the background. |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 } | 775 } |
| 758 | 776 |
| 759 void BrowserViewRenderer::DidComposite() { | 777 void BrowserViewRenderer::DidComposite() { |
| 760 block_invalidates_ = false; | 778 block_invalidates_ = false; |
| 761 post_fallback_tick_.Cancel(); | 779 post_fallback_tick_.Cancel(); |
| 762 fallback_tick_fired_.Cancel(); | 780 fallback_tick_fired_.Cancel(); |
| 763 fallback_tick_pending_ = false; | 781 fallback_tick_pending_ = false; |
| 764 EnsureContinuousInvalidation(false, false); | 782 EnsureContinuousInvalidation(false, false); |
| 765 } | 783 } |
| 766 | 784 |
| 767 void BrowserViewRenderer::SkippedCompositeInDraw() { | 785 void BrowserViewRenderer::DidSkipCompositeInDraw() { |
| 768 block_invalidates_ = false; | 786 block_invalidates_ = false; |
| 769 EnsureContinuousInvalidation(false, true); | 787 EnsureContinuousInvalidation(true, true); |
| 770 } | 788 } |
| 771 | 789 |
| 772 std::string BrowserViewRenderer::ToString() const { | 790 std::string BrowserViewRenderer::ToString() const { |
| 773 std::string str; | 791 std::string str; |
| 774 base::StringAppendF(&str, "is_paused: %d ", is_paused_); | 792 base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
| 775 base::StringAppendF(&str, "view_visible: %d ", view_visible_); | 793 base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
| 776 base::StringAppendF(&str, "window_visible: %d ", window_visible_); | 794 base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
| 777 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 795 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
| 778 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 796 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
| 779 base::StringAppendF(&str, | 797 base::StringAppendF(&str, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 790 base::StringAppendF(&str, | 808 base::StringAppendF(&str, |
| 791 "overscroll_rounding_error_: %s ", | 809 "overscroll_rounding_error_: %s ", |
| 792 overscroll_rounding_error_.ToString().c_str()); | 810 overscroll_rounding_error_.ToString().c_str()); |
| 793 base::StringAppendF( | 811 base::StringAppendF( |
| 794 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); | 812 &str, "on_new_picture_enable: %d ", on_new_picture_enable_); |
| 795 base::StringAppendF(&str, "clear_view: %d ", clear_view_); | 813 base::StringAppendF(&str, "clear_view: %d ", clear_view_); |
| 796 return str; | 814 return str; |
| 797 } | 815 } |
| 798 | 816 |
| 799 } // namespace android_webview | 817 } // namespace android_webview |
| OLD | NEW |