summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authorsunnyps <sunnyps@chromium.org>2015-04-01 17:51:03 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-02 00:51:26 +0000
commitb6ee9a21654e8690a6ff2feee05247f071567692 (patch)
treea4384dc1c649f7a83f4483228ccc1f33b0c32013 /android_webview
parent64150bb3c9ad4efcdb80a6cff9c4e23f3436f535 (diff)
downloadchromium_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')
-rw-r--r--android_webview/browser/browser_view_renderer.cc118
-rw-r--r--android_webview/browser/browser_view_renderer.h22
-rw-r--r--android_webview/browser/browser_view_renderer_client.h2
-rw-r--r--android_webview/browser/browser_view_renderer_unittest.cc41
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_;
};