Index: android_webview/browser/browser_view_renderer.cc |
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc |
index 9d660fb5bfa41fc402bdf38e536f1ba8a682f208..4adf19bf7115a75c5c389396b9e635f0f47cf7c2 100644 |
--- a/android_webview/browser/browser_view_renderer.cc |
+++ b/android_webview/browser/browser_view_renderer.cc |
@@ -66,10 +66,7 @@ BrowserViewRenderer::BrowserViewRenderer( |
page_scale_factor_(1.0), |
on_new_picture_enable_(false), |
clear_view_(false), |
- compositor_needs_continuous_invalidate_(false), |
- invalidate_after_composite_(false), |
- block_invalidates_(false), |
- fallback_tick_pending_(false) { |
+ compositor_needs_vsyncs_(false) { |
} |
BrowserViewRenderer::~BrowserViewRenderer() { |
@@ -119,7 +116,6 @@ void BrowserViewRenderer::TrimMemory(const int level, const bool visible) { |
// Just set the memory limit to 0 and drop all tiles. This will be reset to |
// normal levels in the next DrawGL call. |
compositor_->SetMemoryPolicy(0u); |
- ForceFakeCompositeSW(); |
} |
size_t BrowserViewRenderer::CalculateDesiredMemoryPolicy() { |
@@ -176,7 +172,6 @@ bool BrowserViewRenderer::OnDrawHardware() { |
TRACE_EVENT_INSTANT0("android_webview", |
"EarlyOut_PreviousFrameUnconsumed", |
TRACE_EVENT_SCOPE_THREAD); |
- DidSkipCompositeInDraw(); |
return true; |
} |
@@ -220,8 +215,6 @@ scoped_ptr<cc::CompositorFrame> BrowserViewRenderer::CompositeHw() { |
clip, |
viewport_rect_for_tile_priority, |
transform_for_tile_priority); |
- if (frame.get()) |
- DidComposite(); |
return frame.Pass(); |
} |
@@ -234,7 +227,7 @@ void BrowserViewRenderer::UpdateParentDrawConstraints() { |
!parent_draw_constraints_.Equals( |
shared_renderer_state_.GetParentDrawConstraintsOnUI())) { |
shared_renderer_state_.SetForceInvalidateOnNextDrawGLOnUI(false); |
- EnsureContinuousInvalidation(true, needs_force_invalidate); |
+ PostInvalidate(); |
} |
} |
@@ -258,11 +251,6 @@ void BrowserViewRenderer::ReturnResourceFromParent() { |
} |
} |
-void BrowserViewRenderer::DidSkipCommitFrame() { |
- // Treat it the same way as skipping onDraw. |
- DidSkipCompositeInDraw(); |
-} |
- |
void BrowserViewRenderer::InvalidateOnFunctorDestroy() { |
client_->InvalidateOnFunctorDestroy(); |
} |
@@ -312,8 +300,16 @@ void BrowserViewRenderer::ClearView() { |
return; |
clear_view_ = true; |
- // Always invalidate ignoring the compositor to actually clear the webview. |
- EnsureContinuousInvalidation(true, false); |
+ |
+ PostInvalidate(); |
+} |
+ |
+void BrowserViewRenderer::OnVSync(base::TimeTicks frame_time, |
+ base::TimeDelta vsync_period) { |
+ DCHECK(needs_vsyncs_); |
+ |
+ if (needs_vsyncs_) |
+ client_->RequestVSyncUpdate(); |
} |
void BrowserViewRenderer::SetIsPaused(bool paused) { |
@@ -323,7 +319,7 @@ void BrowserViewRenderer::SetIsPaused(bool paused) { |
"paused", |
paused); |
is_paused_ = paused; |
- EnsureContinuousInvalidation(false, false); |
+ UpdateNeedsVSyncs(); |
} |
void BrowserViewRenderer::SetViewVisibility(bool view_visible) { |
@@ -333,6 +329,7 @@ void BrowserViewRenderer::SetViewVisibility(bool view_visible) { |
"view_visible", |
view_visible); |
view_visible_ = view_visible; |
+ UpdateNeedsVSyncs(); |
} |
void BrowserViewRenderer::SetWindowVisibility(bool window_visible) { |
@@ -342,7 +339,7 @@ void BrowserViewRenderer::SetWindowVisibility(bool window_visible) { |
"window_visible", |
window_visible); |
window_visible_ = window_visible; |
- EnsureContinuousInvalidation(false, false); |
+ UpdateNeedsVSyncs(); |
} |
void BrowserViewRenderer::OnSizeChanged(int width, int height) { |
@@ -412,18 +409,14 @@ void BrowserViewRenderer::DidDestroyCompositor( |
compositor_ = NULL; |
} |
-void BrowserViewRenderer::SetContinuousInvalidate(bool invalidate) { |
- if (compositor_needs_continuous_invalidate_ == invalidate) |
- return; |
- |
- TRACE_EVENT_INSTANT1("android_webview", |
- "BrowserViewRenderer::SetContinuousInvalidate", |
- TRACE_EVENT_SCOPE_THREAD, |
- "invalidate", |
- invalidate); |
- compositor_needs_continuous_invalidate_ = invalidate; |
+void BrowserViewRenderer::SetNeedsVSyncs(bool needs_vsyncs) { |
+ compositor_needs_vsyncs_ = needs_vsyncs; |
+ UpdateNeedsVSyncs(); |
+} |
- EnsureContinuousInvalidation(false, false); |
+void BrowserViewRenderer::PostInvalidate() { |
+ DCHECK(client_); |
+ client_->PostInvalidate(); |
} |
void BrowserViewRenderer::SetDipScale(float dip_scale) { |
@@ -589,126 +582,22 @@ void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, |
client_->DidOverscroll(rounded_overscroll_delta); |
} |
-void BrowserViewRenderer::EnsureContinuousInvalidation( |
- bool force_invalidate, |
- bool skip_reschedule_tick) { |
- if (force_invalidate) |
- invalidate_after_composite_ = true; |
- |
- // This method should be called again when any of these conditions change. |
- bool need_invalidate = |
- compositor_needs_continuous_invalidate_ || invalidate_after_composite_; |
- if (!need_invalidate || block_invalidates_) |
- return; |
- |
- if (!compositor_needs_continuous_invalidate_ && invalidate_after_composite_) |
- invalidate_after_composite_ = false; |
- |
- // Always call view invalidate. We rely the Android framework to ignore the |
- // invalidate when it's not needed such as when view is not visible. |
- client_->PostInvalidate(); |
- |
- // Stop fallback ticks when one of these is true. |
- // 1) Webview is paused. Also need to check we are not in clear view since |
- // paused, offscreen still expect clear view to recover. |
- // 2) If we are attached to window and the window is not visible (eg when |
- // app is in the background). We are sure in this case the webview is used |
- // "on-screen" but that updates are not needed when in the background. |
- bool throttle_fallback_tick = |
- (is_paused_ && !clear_view_) || (attached_to_window_ && !window_visible_); |
- if (throttle_fallback_tick) |
- return; |
- |
- block_invalidates_ = compositor_needs_continuous_invalidate_; |
- if (skip_reschedule_tick && fallback_tick_pending_) |
- return; |
- |
- // Unretained here is safe because the callbacks are cancelled when |
- // they are destroyed. |
- post_fallback_tick_.Reset(base::Bind(&BrowserViewRenderer::PostFallbackTick, |
- base::Unretained(this))); |
- fallback_tick_fired_.Cancel(); |
- fallback_tick_pending_ = false; |
- |
- // No need to reschedule fallback tick if compositor does not need to be |
- // ticked. This can happen if this is reached because force_invalidate is |
- // true. |
- if (compositor_needs_continuous_invalidate_) { |
- fallback_tick_pending_ = true; |
- ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback()); |
- } |
-} |
- |
-void BrowserViewRenderer::PostFallbackTick() { |
- DCHECK(fallback_tick_fired_.IsCancelled()); |
- fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired, |
- base::Unretained(this))); |
- if (compositor_needs_continuous_invalidate_) { |
- ui_task_runner_->PostDelayedTask( |
- FROM_HERE, |
- fallback_tick_fired_.callback(), |
- base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); |
- } else { |
- // Pretend we just composited to unblock further invalidates. |
- DidComposite(); |
- } |
-} |
- |
-void BrowserViewRenderer::FallbackTickFired() { |
- TRACE_EVENT1("android_webview", |
- "BrowserViewRenderer::FallbackTickFired", |
- "compositor_needs_continuous_invalidate_", |
- compositor_needs_continuous_invalidate_); |
- |
- // This should only be called if OnDraw or DrawGL did not come in time, which |
- // means block_invalidates_ must still be true. |
- DCHECK(block_invalidates_); |
- fallback_tick_pending_ = false; |
- if (compositor_needs_continuous_invalidate_ && compositor_) { |
- if (hardware_enabled_) { |
- ReturnResourceFromParent(); |
- ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); |
- scoped_ptr<cc::CompositorFrame> frame = CompositeHw(); |
- if (frame.get()) { |
- shared_renderer_state_.SetCompositorFrameOnUI(frame.Pass(), true); |
- } |
- } else { |
- ForceFakeCompositeSW(); |
- } |
- } else { |
- // Pretend we just composited to unblock further invalidates. |
- DidComposite(); |
- } |
-} |
- |
-void BrowserViewRenderer::ForceFakeCompositeSW() { |
- DCHECK(compositor_); |
- SkBitmap bitmap; |
- bitmap.allocN32Pixels(1, 1); |
- bitmap.eraseColor(0); |
- SkCanvas canvas(bitmap); |
- CompositeSW(&canvas); |
-} |
- |
bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { |
DCHECK(compositor_); |
ReturnResourceFromParent(); |
- bool result = compositor_->DemandDrawSw(canvas); |
- DidComposite(); |
- return result; |
+ return compositor_->DemandDrawSw(canvas); |
} |
-void BrowserViewRenderer::DidComposite() { |
- block_invalidates_ = false; |
- post_fallback_tick_.Cancel(); |
- fallback_tick_fired_.Cancel(); |
- fallback_tick_pending_ = false; |
- EnsureContinuousInvalidation(false, false); |
-} |
+void BrowserViewRenderer::UpdateNeedsVSyncs() { |
+ bool needs_vsyncs = !is_paused_ && IsVisible() && compositor_needs_vsyncs_; |
+ |
+ if (needs_vsyncs_ == needs_vsyncs) |
+ return; |
+ |
+ needs_vsyncs_ = needs_vsyncs; |
-void BrowserViewRenderer::DidSkipCompositeInDraw() { |
- block_invalidates_ = false; |
- EnsureContinuousInvalidation(true, true); |
+ if (needs_vsyncs_) |
+ client_->RequestVSyncUpdate(); |
} |
std::string BrowserViewRenderer::ToString() const { |
@@ -719,9 +608,8 @@ std::string BrowserViewRenderer::ToString() const { |
base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); |
base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); |
base::StringAppendF(&str, |
- "compositor_needs_continuous_invalidate: %d ", |
- compositor_needs_continuous_invalidate_); |
- base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); |
+ "compositor_needs_vsyncs_: %d ", |
+ compositor_needs_vsyncs_); |
base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); |
base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); |
base::StringAppendF(&str, |