diff options
author | sunnyps <sunnyps@chromium.org> | 2015-04-01 17:51:03 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-02 00:51:26 +0000 |
commit | b6ee9a21654e8690a6ff2feee05247f071567692 (patch) | |
tree | a4384dc1c649f7a83f4483228ccc1f33b0c32013 /android_webview | |
parent | 64150bb3c9ad4efcdb80a6cff9c4e23f3436f535 (diff) | |
download | chromium_src-b6ee9a21654e8690a6ff2feee05247f071567692.zip chromium_src-b6ee9a21654e8690a6ff2feee05247f071567692.tar.gz chromium_src-b6ee9a21654e8690a6ff2feee05247f071567692.tar.bz2 |
Revert of cc: Make scheduling be driven by vsync for android webview. (patchset #37 id:720001 of https://codereview.chromium.org/817603002/)
Reason for revert:
Caused failures on memory bot.
Original issue's description:
> cc: Make scheduling be driven by vsync for android webview.
>
> This CL makes android webview use the similar mechanisms for
> scheduling as other platforms instead of using special
> polling code in the scheduler.
>
> Design Doc: https://docs.google.com/a/chromium.org/document/d/1w5UiuA2uZcAiU9-1Y23bxXaStUThkAK8wHI4ULqho2Y/edit#
>
> BUG=439275
>
> Committed: https://crrev.com/bf27da634790bb6eecf4b89f278cfd55c5e5d1f3
> Cr-Commit-Position: refs/heads/master@{#323361}
TBR=brianderson@chromium.org,boliu@chromium.org,enne@chromium.org,danakj@chromium.org,hush@chromium.org,mithro@mithis.com,jdduke@chromium.org,sievers@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=439275
Review URL: https://codereview.chromium.org/1052103002
Cr-Commit-Position: refs/heads/master@{#323382}
Diffstat (limited to 'android_webview')
4 files changed, 115 insertions, 68 deletions
diff --git a/android_webview/browser/browser_view_renderer.cc b/android_webview/browser/browser_view_renderer.cc index 928a62b7..6b4ee92 100644 --- a/android_webview/browser/browser_view_renderer.cc +++ b/android_webview/browser/browser_view_renderer.cc @@ -98,6 +98,8 @@ BrowserViewRenderer::BrowserViewRenderer( on_new_picture_enable_(false), clear_view_(false), offscreen_pre_raster_(false), + compositor_needs_continuous_invalidate_(false), + block_invalidates_(false), fallback_tick_pending_(false) { } @@ -196,7 +198,6 @@ bool BrowserViewRenderer::CanOnDraw() { bool BrowserViewRenderer::OnDrawHardware() { TRACE_EVENT0("android_webview", "BrowserViewRenderer::OnDrawHardware"); - shared_renderer_state_.InitializeHardwareDrawIfNeededOnUI(); if (!CanOnDraw()) { @@ -219,8 +220,6 @@ bool BrowserViewRenderer::OnDrawHardware() { } bool BrowserViewRenderer::CompositeHw() { - CancelFallbackTick(); - ReturnResourceFromParent(); compositor_->SetMemoryPolicy(CalculateDesiredMemoryPolicy()); @@ -264,6 +263,7 @@ bool BrowserViewRenderer::CompositeHw() { transform_for_tile_priority, offscreen_pre_raster_, parent_draw_constraints.is_layer)); + DidComposite(); // Uncommitted frame can happen with consecutive fallback ticks. ReturnUnusedResource(shared_renderer_state_.PassUncommittedFrameOnUI()); shared_renderer_state_.SetCompositorFrameOnUI(child_frame.Pass()); @@ -271,7 +271,7 @@ bool BrowserViewRenderer::CompositeHw() { } void BrowserViewRenderer::UpdateParentDrawConstraints() { - PostInvalidateWithFallback(); + EnsureContinuousInvalidation(true); ParentCompositorDrawConstraints parent_draw_constraints = shared_renderer_state_.GetParentDrawConstraintsOnUI(); client_->ParentDrawConstraintsUpdated(parent_draw_constraints); @@ -342,7 +342,7 @@ void BrowserViewRenderer::ClearView() { clear_view_ = true; // Always invalidate ignoring the compositor to actually clear the webview. - PostInvalidateWithFallback(); + EnsureContinuousInvalidation(true); } void BrowserViewRenderer::SetOffscreenPreRaster(bool enable) { @@ -357,7 +357,7 @@ void BrowserViewRenderer::SetIsPaused(bool paused) { "paused", paused); is_paused_ = paused; - UpdateCompositorIsActive(); + EnsureContinuousInvalidation(false); } void BrowserViewRenderer::SetViewVisibility(bool view_visible) { @@ -376,7 +376,7 @@ void BrowserViewRenderer::SetWindowVisibility(bool window_visible) { "window_visible", window_visible); window_visible_ = window_visible; - UpdateCompositorIsActive(); + EnsureContinuousInvalidation(false); } void BrowserViewRenderer::OnSizeChanged(int width, int height) { @@ -399,7 +399,6 @@ void BrowserViewRenderer::OnAttachedToWindow(int width, int height) { height); attached_to_window_ = true; size_.SetSize(width, height); - UpdateCompositorIsActive(); } void BrowserViewRenderer::OnDetachedFromWindow() { @@ -407,7 +406,6 @@ void BrowserViewRenderer::OnDetachedFromWindow() { shared_renderer_state_.ReleaseHardwareDrawIfNeededOnUI(); attached_to_window_ = false; DCHECK(!hardware_enabled_); - UpdateCompositorIsActive(); } void BrowserViewRenderer::ReleaseHardware() { @@ -439,7 +437,6 @@ void BrowserViewRenderer::DidInitializeCompositor( DCHECK(compositor); DCHECK(!compositor_); compositor_ = compositor; - UpdateCompositorIsActive(); } void BrowserViewRenderer::DidDestroyCompositor( @@ -449,6 +446,20 @@ 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; + + EnsureContinuousInvalidation(false); +} + void BrowserViewRenderer::SetDipScale(float dip_scale) { dip_scale_ = dip_scale; CHECK_GT(dip_scale_, 0.f); @@ -616,13 +627,13 @@ void BrowserViewRenderer::DidOverscroll(gfx::Vector2dF accumulated_overscroll, client_->DidOverscroll(rounded_overscroll_delta); } -void BrowserViewRenderer::PostInvalidate() { - TRACE_EVENT_INSTANT0("android_webview", "BrowserViewRenderer::PostInvalidate", - TRACE_EVENT_SCOPE_THREAD); - PostInvalidateWithFallback(); -} +void BrowserViewRenderer::EnsureContinuousInvalidation(bool force_invalidate) { + // This method should be called again when any of these conditions change. + bool need_invalidate = + compositor_needs_continuous_invalidate_ || force_invalidate; + if (!need_invalidate || block_invalidates_) + return; -void BrowserViewRenderer::PostInvalidateWithFallback() { // 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(); @@ -635,49 +646,63 @@ void BrowserViewRenderer::PostInvalidateWithFallback() { // "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 || fallback_tick_pending_) + if (throttle_fallback_tick) return; - DCHECK(post_fallback_tick_.IsCancelled()); - DCHECK(fallback_tick_fired_.IsCancelled()); + block_invalidates_ = compositor_needs_continuous_invalidate_; + if (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))); - ui_task_runner_->PostTask(FROM_HERE, post_fallback_tick_.callback()); - fallback_tick_pending_ = true; -} - -void BrowserViewRenderer::CancelFallbackTick() { - post_fallback_tick_.Cancel(); 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()); - TRACE_EVENT0("android_webview", "BrowserViewRenderer::PostFallbackTick"); - post_fallback_tick_.Cancel(); fallback_tick_fired_.Reset(base::Bind(&BrowserViewRenderer::FallbackTickFired, base::Unretained(this))); - ui_task_runner_->PostDelayedTask( - FROM_HERE, fallback_tick_fired_.callback(), - base::TimeDelta::FromMilliseconds(kFallbackTickTimeoutInMilliseconds)); + 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_EVENT0("android_webview", "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 fallback_tick_pending_ must still be true. - DCHECK(fallback_tick_pending_); - fallback_tick_fired_.Cancel(); + // means block_invalidates_ must still be true. + DCHECK(block_invalidates_); fallback_tick_pending_ = false; - if (compositor_) { + if (compositor_needs_continuous_invalidate_ && compositor_) { if (hardware_enabled_) { CompositeHw(); } else { ForceFakeCompositeSW(); } + } else { + // Pretend we just composited to unblock further invalidates. + DidComposite(); } } @@ -692,15 +717,18 @@ void BrowserViewRenderer::ForceFakeCompositeSW() { bool BrowserViewRenderer::CompositeSW(SkCanvas* canvas) { DCHECK(compositor_); - CancelFallbackTick(); ReturnResourceFromParent(); - return compositor_->DemandDrawSw(canvas); + bool result = compositor_->DemandDrawSw(canvas); + DidComposite(); + return result; } -void BrowserViewRenderer::UpdateCompositorIsActive() { - if (compositor_) - compositor_->SetIsActive(!is_paused_ && - (!attached_to_window_ || window_visible_)); +void BrowserViewRenderer::DidComposite() { + block_invalidates_ = false; + post_fallback_tick_.Cancel(); + fallback_tick_fired_.Cancel(); + fallback_tick_pending_ = false; + EnsureContinuousInvalidation(false); } std::string BrowserViewRenderer::ToString() const { @@ -710,8 +738,10 @@ std::string BrowserViewRenderer::ToString() const { base::StringAppendF(&str, "window_visible: %d ", window_visible_); base::StringAppendF(&str, "dip_scale: %f ", dip_scale_); base::StringAppendF(&str, "page_scale_factor: %f ", page_scale_factor_); - base::StringAppendF(&str, "fallback_tick_pending: %d ", - fallback_tick_pending_); + base::StringAppendF(&str, + "compositor_needs_continuous_invalidate: %d ", + compositor_needs_continuous_invalidate_); + base::StringAppendF(&str, "block_invalidates: %d ", block_invalidates_); base::StringAppendF(&str, "view size: %s ", size_.ToString().c_str()); base::StringAppendF(&str, "attached_to_window: %d ", attached_to_window_); base::StringAppendF(&str, diff --git a/android_webview/browser/browser_view_renderer.h b/android_webview/browser/browser_view_renderer.h index 308abd4..843529b 100644 --- a/android_webview/browser/browser_view_renderer.h +++ b/android_webview/browser/browser_view_renderer.h @@ -96,7 +96,7 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { content::SynchronousCompositor* compositor) override; void DidDestroyCompositor( content::SynchronousCompositor* compositor) override; - void PostInvalidate() override; + void SetContinuousInvalidate(bool invalidate) override; void DidUpdateContent() override; gfx::Vector2dF GetTotalRootLayerScrollOffset() override; void UpdateRootLayerState(const gfx::Vector2dF& total_scroll_offset_dip, @@ -116,13 +116,12 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { private: void SetTotalRootLayerScrollOffset(gfx::Vector2dF new_value_dip); bool CanOnDraw(); - // Posts an invalidate with fallback tick. All invalidates posted while an - // invalidate is pending will be posted as a single invalidate after the - // pending invalidate is done. - void PostInvalidateWithFallback(); - void CancelFallbackTick(); - void UpdateCompositorIsActive(); + // Checks the continuous invalidate and block invalidate state, and schedule + // invalidates appropriately. If |force_invalidate| is true, then send a view + // invalidate regardless of compositor expectation. + void EnsureContinuousInvalidation(bool force_invalidate); bool CompositeSW(SkCanvas* canvas); + void DidComposite(); scoped_refptr<base::trace_event::ConvertableToTraceFormat> RootLayerStateAsValue(const gfx::Vector2dF& total_scroll_offset_dip, const gfx::SizeF& scrollable_size_dip); @@ -146,7 +145,6 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { gfx::Vector2d max_scroll_offset() const; size_t CalculateDesiredMemoryPolicy(); - // For debug tracing or logging. Return the string representation of this // view renderer's state. std::string ToString() const; @@ -172,6 +170,14 @@ class BrowserViewRenderer : public content::SynchronousCompositorClient { gfx::Vector2d last_on_draw_scroll_offset_; gfx::Rect last_on_draw_global_visible_rect_; + // When true, we should continuously invalidate and keep drawing, for example + // to drive animation. This value is set by the compositor and should always + // reflect the expectation of the compositor and not be reused for other + // states. + bool compositor_needs_continuous_invalidate_; + + // Used to block additional invalidates while one is already pending. + bool block_invalidates_; base::CancelableClosure post_fallback_tick_; base::CancelableClosure fallback_tick_fired_; diff --git a/android_webview/browser/browser_view_renderer_client.h b/android_webview/browser/browser_view_renderer_client.h index c4bf8f2..4c2f36f 100644 --- a/android_webview/browser/browser_view_renderer_client.h +++ b/android_webview/browser/browser_view_renderer_client.h @@ -26,8 +26,6 @@ class BrowserViewRendererClient { virtual void OnNewPicture() = 0; // Called to trigger view invalidations. - // This calls postInvalidateOnAnimation if outside of a vsync, otherwise it - // calls invalidate. virtual void PostInvalidate() = 0; // Call postInvalidateOnAnimation for invalidations. This is only used to diff --git a/android_webview/browser/browser_view_renderer_unittest.cc b/android_webview/browser/browser_view_renderer_unittest.cc index 634e1f3..e4c6eac 100644 --- a/android_webview/browser/browser_view_renderer_unittest.cc +++ b/android_webview/browser/browser_view_renderer_unittest.cc @@ -9,7 +9,13 @@ namespace android_webview { class SmokeTest : public RenderingTest { - void StartTest() override { browser_view_renderer_->PostInvalidate(); } + void StartTest() override { + browser_view_renderer_->SetContinuousInvalidate(true); + } + + void WillOnDraw() override { + browser_view_renderer_->SetContinuousInvalidate(false); + } void DidDrawOnRT(SharedRendererState* functor) override { EndTest(); @@ -20,20 +26,25 @@ RENDERING_TEST_F(SmokeTest); class ClearViewTest : public RenderingTest { public: - ClearViewTest() : on_draw_count_(0) {} + ClearViewTest() : on_draw_count_(0u) {} void StartTest() override { - browser_view_renderer_->PostInvalidate(); + browser_view_renderer_->SetContinuousInvalidate(true); browser_view_renderer_->ClearView(); } - void DidOnDraw(bool success) override { + void WillOnDraw() override { on_draw_count_++; - if (on_draw_count_ == 1) { + if (on_draw_count_ == 2u) { + browser_view_renderer_->SetContinuousInvalidate(false); + } + } + + void DidOnDraw(bool success) override { + if (on_draw_count_ == 1u) { // First OnDraw should be skipped due to ClearView. EXPECT_FALSE(success); browser_view_renderer_->DidUpdateContent(); // Unset ClearView. - browser_view_renderer_->PostInvalidate(); } else { // Following OnDraws should succeed. EXPECT_TRUE(success); @@ -44,23 +55,25 @@ class ClearViewTest : public RenderingTest { EndTest(); } private: - int on_draw_count_; + size_t on_draw_count_; }; RENDERING_TEST_F(ClearViewTest); class TestAnimateInAndOutOfScreen : public RenderingTest { public: - TestAnimateInAndOutOfScreen() : on_draw_count_(0), draw_gl_count_on_rt_(0) {} + TestAnimateInAndOutOfScreen() + : on_draw_count_(0u), draw_gl_count_on_rt_(0u) {} void StartTest() override { new_constraints_ = ParentCompositorDrawConstraints( false, gfx::Transform(), gfx::Rect(window_->surface_size())); new_constraints_.transform.Scale(2.0, 2.0); - browser_view_renderer_->PostInvalidate(); + browser_view_renderer_->SetContinuousInvalidate(true); } void WillOnDraw() override { + browser_view_renderer_->SetContinuousInvalidate(false); // Step 0: A single onDraw on screen. The parent draw constraints // of the BVR will updated to be the initial constraints. // Step 1: A single onDrraw off screen. The parent draw constraints of the @@ -68,7 +81,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { // Step 2: This onDraw is to introduce the DrawGL that animates the // webview onto the screen on render thread. End the test when the parent // draw constraints of BVR is updated to initial constraints. - if (on_draw_count_ == 1 || on_draw_count_ == 2) + if (on_draw_count_ == 1u || on_draw_count_ == 2u) browser_view_renderer_->PrepareToDraw(gfx::Vector2d(), gfx::Rect()); } @@ -79,7 +92,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { bool WillDrawOnRT(SharedRendererState* functor, AwDrawGLInfo* draw_info) override { - if (draw_gl_count_on_rt_ == 1) { + if (draw_gl_count_on_rt_ == 1u) { draw_gl_count_on_rt_++; ui_proxy_->PostTask(FROM_HERE, base::Bind(&RenderingTest::PostInvalidate, base::Unretained(this))); @@ -91,7 +104,7 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { draw_info->is_layer = false; gfx::Transform transform; - if (draw_gl_count_on_rt_ == 0) + if (draw_gl_count_on_rt_ == 0u) transform = new_constraints_.transform; transform.matrix().asColMajorf(draw_info->transform); @@ -132,8 +145,8 @@ class TestAnimateInAndOutOfScreen : public RenderingTest { } private: - int on_draw_count_; - int draw_gl_count_on_rt_; + size_t on_draw_count_; + size_t draw_gl_count_on_rt_; ParentCompositorDrawConstraints initial_constraints_; ParentCompositorDrawConstraints new_constraints_; }; |