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 "android_webview/public/browser/draw_gl.h" | 10 #include "android_webview/public/browser/draw_gl.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 is_paused_(false), | 126 is_paused_(false), |
127 view_visible_(false), | 127 view_visible_(false), |
128 window_visible_(false), | 128 window_visible_(false), |
129 attached_to_window_(false), | 129 attached_to_window_(false), |
130 hardware_enabled_(false), | 130 hardware_enabled_(false), |
131 dip_scale_(0.0), | 131 dip_scale_(0.0), |
132 page_scale_factor_(1.0), | 132 page_scale_factor_(1.0), |
133 on_new_picture_enable_(false), | 133 on_new_picture_enable_(false), |
134 clear_view_(false), | 134 clear_view_(false), |
135 compositor_needs_continuous_invalidate_(false), | 135 compositor_needs_continuous_invalidate_(false), |
| 136 invalidate_after_composite_(false), |
136 block_invalidates_(false), | 137 block_invalidates_(false), |
137 fallback_tick_pending_(false), | 138 fallback_tick_pending_(false), |
138 width_(0), | 139 width_(0), |
139 height_(0) { | 140 height_(0) { |
140 CHECK(web_contents_); | 141 CHECK(web_contents_); |
141 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); | 142 content::SynchronousCompositor::SetClientForWebContents(web_contents_, this); |
142 | 143 |
143 // Currently the logic in this class relies on |compositor_| remaining | 144 // Currently the logic in this class relies on |compositor_| remaining |
144 // NULL until the DidInitializeCompositor() call, hence it is not set here. | 145 // NULL until the DidInitializeCompositor() call, hence it is not set here. |
145 } | 146 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 // Perform a software draw | 253 // Perform a software draw |
253 return OnDrawSoftware(java_canvas); | 254 return OnDrawSoftware(java_canvas); |
254 } | 255 } |
255 | 256 |
256 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { | 257 bool BrowserViewRenderer::OnDrawHardware(jobject java_canvas) { |
257 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); | 258 TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); |
258 if (!compositor_) | 259 if (!compositor_) |
259 return false; | 260 return false; |
260 | 261 |
261 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); | 262 shared_renderer_state_->SetScrollOffset(last_on_draw_scroll_offset_); |
262 if (last_on_draw_global_visible_rect_.IsEmpty()) { | |
263 TRACE_EVENT_INSTANT0("android_webview", | |
264 "EarlyOut_EmptyVisibleRect", | |
265 TRACE_EVENT_SCOPE_THREAD); | |
266 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); | |
267 return client_->RequestDrawGL(java_canvas, false); | |
268 } | |
269 | 263 |
270 if (!hardware_enabled_) { | 264 if (!hardware_enabled_) { |
271 hardware_enabled_ = compositor_->InitializeHwDraw(); | 265 hardware_enabled_ = compositor_->InitializeHwDraw(); |
272 if (hardware_enabled_) { | 266 if (hardware_enabled_) { |
273 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); | 267 tile_manager_key_ = GlobalTileManager::GetInstance()->PushBack(this); |
274 } | 268 } |
275 } | 269 } |
276 if (!hardware_enabled_) | 270 if (!hardware_enabled_) |
277 return false; | 271 return false; |
278 | 272 |
| 273 if (last_on_draw_global_visible_rect_.IsEmpty() && |
| 274 parent_draw_constraints_.surface_rect.IsEmpty()) { |
| 275 TRACE_EVENT_INSTANT0("android_webview", |
| 276 "EarlyOut_EmptyVisibleRect", |
| 277 TRACE_EVENT_SCOPE_THREAD); |
| 278 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(true); |
| 279 return client_->RequestDrawGL(java_canvas, false); |
| 280 } |
| 281 |
279 ReturnResourceFromParent(); | 282 ReturnResourceFromParent(); |
280 if (shared_renderer_state_->HasCompositorFrame()) { | 283 if (shared_renderer_state_->HasCompositorFrame()) { |
281 TRACE_EVENT_INSTANT0("android_webview", | 284 TRACE_EVENT_INSTANT0("android_webview", |
282 "EarlyOut_PreviousFrameUnconsumed", | 285 "EarlyOut_PreviousFrameUnconsumed", |
283 TRACE_EVENT_SCOPE_THREAD); | 286 TRACE_EVENT_SCOPE_THREAD); |
284 SkippedCompositeInDraw(); | 287 DidSkipCompositeInDraw(); |
285 return client_->RequestDrawGL(java_canvas, false); | 288 return client_->RequestDrawGL(java_canvas, false); |
286 } | 289 } |
287 | 290 |
288 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); | 291 scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); |
289 if (!frame.get()) | 292 if (!frame.get()) |
290 return false; | 293 return false; |
291 | 294 |
292 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); | 295 shared_renderer_state_->SetCompositorFrame(frame.Pass(), false); |
293 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); | 296 GlobalTileManager::GetInstance()->DidUse(tile_manager_key_); |
294 return client_->RequestDrawGL(java_canvas, false); | 297 return client_->RequestDrawGL(java_canvas, false); |
295 } | 298 } |
296 | 299 |
297 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { | 300 scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { |
298 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); | 301 SynchronousCompositorMemoryPolicy new_policy = CalculateDesiredMemoryPolicy(); |
299 RequestMemoryPolicy(new_policy); | 302 RequestMemoryPolicy(new_policy); |
300 compositor_->SetMemoryPolicy(memory_policy_); | 303 compositor_->SetMemoryPolicy(memory_policy_); |
301 | 304 |
302 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); | 305 parent_draw_constraints_ = shared_renderer_state_->ParentDrawConstraints(); |
303 gfx::Size surface_size(width_, height_); | 306 gfx::Size surface_size(width_, height_); |
304 gfx::Rect viewport(surface_size); | 307 gfx::Rect viewport(surface_size); |
305 gfx::Rect clip = viewport; | 308 gfx::Rect clip = viewport; |
306 gfx::Transform transform_for_tile_priority = | 309 gfx::Transform transform_for_tile_priority = |
307 parent_draw_constraints_.transform; | 310 parent_draw_constraints_.transform; |
308 | 311 |
309 // If the WebView is on a layer, WebView does not know what transform is | 312 // If the WebView is on a layer, WebView does not know what transform is |
310 // applied onto the layer so global visible rect does not make sense here. | 313 // applied onto the layer so global visible rect does not make sense here. |
311 // In this case, just use the surface rect for tiling. | 314 // In this case, just use the surface rect for tiling. |
312 gfx::Rect viewport_rect_for_tile_priority; | 315 gfx::Rect viewport_rect_for_tile_priority; |
313 if (parent_draw_constraints_.is_layer) | 316 if (parent_draw_constraints_.is_layer || |
| 317 last_on_draw_global_visible_rect_.IsEmpty()) { |
314 viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; | 318 viewport_rect_for_tile_priority = parent_draw_constraints_.surface_rect; |
315 else | 319 } else { |
316 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; | 320 viewport_rect_for_tile_priority = last_on_draw_global_visible_rect_; |
| 321 } |
317 | 322 |
318 scoped_ptr<cc::CompositorFrame> frame = | 323 scoped_ptr<cc::CompositorFrame> frame = |
319 compositor_->DemandDrawHw(surface_size, | 324 compositor_->DemandDrawHw(surface_size, |
320 gfx::Transform(), | 325 gfx::Transform(), |
321 viewport, | 326 viewport, |
322 clip, | 327 clip, |
323 viewport_rect_for_tile_priority, | 328 viewport_rect_for_tile_priority, |
324 transform_for_tile_priority); | 329 transform_for_tile_priority); |
325 if (frame.get()) | 330 if (frame.get()) |
326 DidComposite(); | 331 DidComposite(); |
327 return frame.Pass(); | 332 return frame.Pass(); |
328 } | 333 } |
329 | 334 |
330 void BrowserViewRenderer::UpdateParentDrawConstraints() { | 335 void BrowserViewRenderer::UpdateParentDrawConstraints() { |
331 // Post an invalidate if the parent draw constraints are stale and there is | 336 // Post an invalidate if the parent draw constraints are stale and there is |
332 // no pending invalidate. | 337 // no pending invalidate. |
333 if (shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL() || | 338 bool needs_force_invalidate = |
| 339 shared_renderer_state_->NeedsForceInvalidateOnNextDrawGL(); |
| 340 if (needs_force_invalidate || |
334 !parent_draw_constraints_.Equals( | 341 !parent_draw_constraints_.Equals( |
335 shared_renderer_state_->ParentDrawConstraints())) { | 342 shared_renderer_state_->ParentDrawConstraints())) { |
336 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(false); | 343 shared_renderer_state_->SetForceInvalidateOnNextDrawGL(false); |
337 EnsureContinuousInvalidation(true, false); | 344 EnsureContinuousInvalidation(true, needs_force_invalidate); |
338 } | 345 } |
339 } | 346 } |
340 | 347 |
341 void BrowserViewRenderer::ReturnUnusedResource( | 348 void BrowserViewRenderer::ReturnUnusedResource( |
342 scoped_ptr<cc::CompositorFrame> frame) { | 349 scoped_ptr<cc::CompositorFrame> frame) { |
343 if (!frame.get()) | 350 if (!frame.get()) |
344 return; | 351 return; |
345 | 352 |
346 cc::CompositorFrameAck frame_ack; | 353 cc::CompositorFrameAck frame_ack; |
347 cc::TransferableResource::ReturnResources( | 354 cc::TransferableResource::ReturnResources( |
348 frame->delegated_frame_data->resource_list, &frame_ack.resources); | 355 frame->delegated_frame_data->resource_list, &frame_ack.resources); |
349 if (compositor_ && !frame_ack.resources.empty()) | 356 if (compositor_ && !frame_ack.resources.empty()) |
350 compositor_->ReturnResources(frame_ack); | 357 compositor_->ReturnResources(frame_ack); |
351 } | 358 } |
352 | 359 |
353 void BrowserViewRenderer::ReturnResourceFromParent() { | 360 void BrowserViewRenderer::ReturnResourceFromParent() { |
354 cc::CompositorFrameAck frame_ack; | 361 cc::CompositorFrameAck frame_ack; |
355 shared_renderer_state_->SwapReturnedResources(&frame_ack.resources); | 362 shared_renderer_state_->SwapReturnedResources(&frame_ack.resources); |
356 if (compositor_ && !frame_ack.resources.empty()) { | 363 if (compositor_ && !frame_ack.resources.empty()) { |
357 compositor_->ReturnResources(frame_ack); | 364 compositor_->ReturnResources(frame_ack); |
358 } | 365 } |
359 } | 366 } |
360 | 367 |
| 368 void BrowserViewRenderer::DidSkipCommitFrame() { |
| 369 // Treat it the same way as skipping onDraw. |
| 370 DidSkipCompositeInDraw(); |
| 371 } |
| 372 |
361 bool BrowserViewRenderer::OnDrawSoftware(jobject java_canvas) { | 373 bool BrowserViewRenderer::OnDrawSoftware(jobject java_canvas) { |
362 if (!compositor_) { | 374 if (!compositor_) { |
363 TRACE_EVENT_INSTANT0( | 375 TRACE_EVENT_INSTANT0( |
364 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); | 376 "android_webview", "EarlyOut_NoCompositor", TRACE_EVENT_SCOPE_THREAD); |
365 return false; | 377 return false; |
366 } | 378 } |
367 | 379 |
368 // TODO(hush): right now webview size is passed in as the auxiliary bitmap | 380 // TODO(hush): right now webview size is passed in as the auxiliary bitmap |
369 // size, which might hurt performace (only for software draws with auxiliary | 381 // size, which might hurt performace (only for software draws with auxiliary |
370 // bitmap). For better performance, get global visible rect, transform it | 382 // bitmap). For better performance, get global visible rect, transform it |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
697 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( | 709 gfx::Vector2d rounded_overscroll_delta = gfx::ToRoundedVector2d( |
698 scaled_overscroll_delta + overscroll_rounding_error_); | 710 scaled_overscroll_delta + overscroll_rounding_error_); |
699 overscroll_rounding_error_ = | 711 overscroll_rounding_error_ = |
700 scaled_overscroll_delta - rounded_overscroll_delta; | 712 scaled_overscroll_delta - rounded_overscroll_delta; |
701 client_->DidOverscroll(rounded_overscroll_delta); | 713 client_->DidOverscroll(rounded_overscroll_delta); |
702 } | 714 } |
703 | 715 |
704 void BrowserViewRenderer::EnsureContinuousInvalidation( | 716 void BrowserViewRenderer::EnsureContinuousInvalidation( |
705 bool force_invalidate, | 717 bool force_invalidate, |
706 bool skip_reschedule_tick) { | 718 bool skip_reschedule_tick) { |
| 719 if (force_invalidate) |
| 720 invalidate_after_composite_ = true; |
| 721 |
707 // This method should be called again when any of these conditions change. | 722 // This method should be called again when any of these conditions change. |
708 bool need_invalidate = | 723 bool need_invalidate = |
709 compositor_needs_continuous_invalidate_ || force_invalidate; | 724 compositor_needs_continuous_invalidate_ || invalidate_after_composite_; |
710 if (!need_invalidate || block_invalidates_) | 725 if (!need_invalidate || block_invalidates_) |
711 return; | 726 return; |
712 | 727 |
| 728 if (!compositor_needs_continuous_invalidate_ && invalidate_after_composite_) |
| 729 invalidate_after_composite_ = false; |
| 730 |
713 // Always call view invalidate. We rely the Android framework to ignore the | 731 // Always call view invalidate. We rely the Android framework to ignore the |
714 // invalidate when it's not needed such as when view is not visible. | 732 // invalidate when it's not needed such as when view is not visible. |
715 client_->PostInvalidate(); | 733 client_->PostInvalidate(); |
716 | 734 |
717 // Stop fallback ticks when one of these is true. | 735 // Stop fallback ticks when one of these is true. |
718 // 1) Webview is paused. Also need to check we are not in clear view since | 736 // 1) Webview is paused. Also need to check we are not in clear view since |
719 // paused, offscreen still expect clear view to recover. | 737 // paused, offscreen still expect clear view to recover. |
720 // 2) If we are attached to window and the window is not visible (eg when | 738 // 2) If we are attached to window and the window is not visible (eg when |
721 // app is in the background). We are sure in this case the webview is used | 739 // app is in the background). We are sure in this case the webview is used |
722 // "on-screen" but that updates are not needed when in the background. | 740 // "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... |
805 } | 823 } |
806 | 824 |
807 void BrowserViewRenderer::DidComposite() { | 825 void BrowserViewRenderer::DidComposite() { |
808 block_invalidates_ = false; | 826 block_invalidates_ = false; |
809 post_fallback_tick_.Cancel(); | 827 post_fallback_tick_.Cancel(); |
810 fallback_tick_fired_.Cancel(); | 828 fallback_tick_fired_.Cancel(); |
811 fallback_tick_pending_ = false; | 829 fallback_tick_pending_ = false; |
812 EnsureContinuousInvalidation(false, false); | 830 EnsureContinuousInvalidation(false, false); |
813 } | 831 } |
814 | 832 |
815 void BrowserViewRenderer::SkippedCompositeInDraw() { | 833 void BrowserViewRenderer::DidSkipCompositeInDraw() { |
816 block_invalidates_ = false; | 834 block_invalidates_ = false; |
817 EnsureContinuousInvalidation(false, true); | 835 EnsureContinuousInvalidation(true, true); |
818 } | 836 } |
819 | 837 |
820 std::string BrowserViewRenderer::ToString(AwDrawGLInfo* draw_info) const { | 838 std::string BrowserViewRenderer::ToString(AwDrawGLInfo* draw_info) const { |
821 std::string str; | 839 std::string str; |
822 base::StringAppendF(&str, "is_paused: %d ", is_paused_); | 840 base::StringAppendF(&str, "is_paused: %d ", is_paused_); |
823 base::StringAppendF(&str, "view_visible: %d ", view_visible_); | 841 base::StringAppendF(&str, "view_visible: %d ", view_visible_); |
824 base::StringAppendF(&str, "window_visible: %d ", window_visible_); | 842 base::StringAppendF(&str, "window_visible: %d ", window_visible_); |
825 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); | 843 base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
826 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); | 844 base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
827 base::StringAppendF(&str, | 845 base::StringAppendF(&str, |
(...skipping 23 matching lines...) Expand all Loading... |
851 base::StringAppendF(&str, | 869 base::StringAppendF(&str, |
852 "surface width height: [%d %d] ", | 870 "surface width height: [%d %d] ", |
853 draw_info->width, | 871 draw_info->width, |
854 draw_info->height); | 872 draw_info->height); |
855 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); | 873 base::StringAppendF(&str, "is_layer: %d ", draw_info->is_layer); |
856 } | 874 } |
857 return str; | 875 return str; |
858 } | 876 } |
859 | 877 |
860 } // namespace android_webview | 878 } // namespace android_webview |
OLD | NEW |