summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authormithro <mithro@mithis.com>2014-11-10 07:36:47 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-10 15:37:19 +0000
commit719bf67948d010b5462993ee1b2697f437053c9c (patch)
tree982e5d8b31d4f1838cb566c5fd33b33f39144d40 /cc
parentf302b0fe8d6f4b237a04696f52277f42ceefbb1a (diff)
downloadchromium_src-719bf67948d010b5462993ee1b2697f437053c9c.zip
chromium_src-719bf67948d010b5462993ee1b2697f437053c9c.tar.gz
chromium_src-719bf67948d010b5462993ee1b2697f437053c9c.tar.bz2
Moving background animation ticking from LayerTreeHostImpl into the Scheduler.
Background ticking currently happens in the LayerTreeHostImpl, this makes it very hard to preserve the monotonicity guarantee needed by frame times. http://crrev.com/267783004 set up the scheduler to become the source of background ticks and this CL makes use of that functionality. BUG=345459 Committed: https://crrev.com/4df3c4366015739a7c6b6c1539a8d7c9198e38ef Cr-Commit-Position: refs/heads/master@{#302757} Committed: https://crrev.com/185438b3e5e3f43ce2996da0022f510fbe193a6e Cr-Commit-Position: refs/heads/master@{#303423} Review URL: https://codereview.chromium.org/595973002 Cr-Commit-Position: refs/heads/master@{#303467}
Diffstat (limited to 'cc')
-rw-r--r--cc/animation/layer_animation_controller.cc6
-rw-r--r--cc/scheduler/scheduler.cc6
-rw-r--r--cc/scheduler/scheduler_settings.cc9
-rw-r--r--cc/scheduler/scheduler_settings.h3
-rw-r--r--cc/scheduler/scheduler_state_machine.cc16
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc2
-rw-r--r--cc/test/layer_tree_test.cc9
-rw-r--r--cc/test/layer_tree_test.h1
-rw-r--r--cc/trees/layer_tree_host_impl.cc100
-rw-r--r--cc/trees/layer_tree_host_impl.h9
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc19
-rw-r--r--cc/trees/layer_tree_settings.cc1
-rw-r--r--cc/trees/layer_tree_settings.h1
-rw-r--r--cc/trees/single_thread_proxy.cc44
-rw-r--r--cc/trees/single_thread_proxy.h2
-rw-r--r--cc/trees/thread_proxy.cc27
-rw-r--r--cc/trees/thread_proxy.h1
17 files changed, 75 insertions, 181 deletions
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index b779a37..e34fc4a 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -212,7 +212,11 @@ void LayerAnimationController::UpdateState(bool start_ready_animations,
if (!HasActiveValueObserver())
return;
- DCHECK(last_tick_time_ != base::TimeTicks());
+ // Animate hasn't been called, this happens if an observer has been added
+ // between the Commit and Draw phases.
+ if (last_tick_time_ == base::TimeTicks())
+ return;
+
if (start_ready_animations)
PromoteStartedAnimations(last_tick_time_, events);
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 88c27c1..4c2316f 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -62,9 +62,9 @@ SchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource(
"SyntheticBeginFrameSource");
DCHECK(!(scheduler->background_frame_source_internal_));
scheduler->background_frame_source_internal_ =
- SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
- scheduler->Now(),
- base::TimeDelta::FromSeconds(1));
+ SyntheticBeginFrameSource::Create(
+ scheduler->task_runner_.get(), scheduler->Now(),
+ scheduler->settings_.background_frame_interval);
return scheduler->background_frame_source_internal_.get();
}
diff --git a/cc/scheduler/scheduler_settings.cc b/cc/scheduler/scheduler_settings.cc
index ab9add0..95294ad 100644
--- a/cc/scheduler/scheduler_settings.cc
+++ b/cc/scheduler/scheduler_settings.cc
@@ -17,7 +17,8 @@ SchedulerSettings::SchedulerSettings()
maximum_number_of_failed_draws_before_draw_is_forced_(3),
using_synchronous_renderer_compositor(false),
throttle_frame_production(true),
- disable_hi_res_timer_tasks_on_battery(false) {
+ disable_hi_res_timer_tasks_on_battery(false),
+ background_frame_interval(base::TimeDelta::FromSeconds(1)) {
}
SchedulerSettings::SchedulerSettings(const LayerTreeSettings& settings)
@@ -33,7 +34,9 @@ SchedulerSettings::SchedulerSettings(const LayerTreeSettings& settings)
settings.using_synchronous_renderer_compositor),
throttle_frame_production(settings.throttle_frame_production),
disable_hi_res_timer_tasks_on_battery(
- settings.disable_hi_res_timer_tasks_on_battery) {
+ settings.disable_hi_res_timer_tasks_on_battery),
+ background_frame_interval(base::TimeDelta::FromSecondsD(
+ 1.0 / settings.background_animation_rate)) {
}
SchedulerSettings::~SchedulerSettings() {}
@@ -56,6 +59,8 @@ SchedulerSettings::AsValue() const {
state->SetBoolean("throttle_frame_production", throttle_frame_production);
state->SetBoolean("disable_hi_res_timer_tasks_on_battery",
disable_hi_res_timer_tasks_on_battery);
+ state->SetInteger("background_frame_interval",
+ background_frame_interval.InMicroseconds());
return state;
}
diff --git a/cc/scheduler/scheduler_settings.h b/cc/scheduler/scheduler_settings.h
index 8607991..561d265 100644
--- a/cc/scheduler/scheduler_settings.h
+++ b/cc/scheduler/scheduler_settings.h
@@ -6,6 +6,7 @@
#define CC_SCHEDULER_SCHEDULER_SETTINGS_H_
#include "base/memory/ref_counted.h"
+#include "base/time/time.h"
#include "base/values.h"
#include "cc/base/cc_export.h"
@@ -33,6 +34,8 @@ class CC_EXPORT SchedulerSettings {
bool throttle_frame_production;
bool disable_hi_res_timer_tasks_on_battery;
+ base::TimeDelta background_frame_interval;
+
scoped_refptr<base::debug::ConvertableToTraceFormat> AsValue() const;
};
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 2b8210d..94016f3 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -423,9 +423,6 @@ bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
}
bool SchedulerStateMachine::ShouldAnimate() const {
- if (!can_draw_)
- return false;
-
// If a commit occurred after our last call, we need to do animation again.
if (HasAnimatedThisFrame() && !did_commit_after_animating_)
return false;
@@ -765,29 +762,18 @@ bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const {
if (!HasInitializedOutputSurface())
return false;
- // If we can't draw, don't tick until we are notified that we can draw again.
- if (!can_draw_)
- return false;
-
// The forced draw respects our normal draw scheduling, so we need to
// request a BeginImplFrame for it.
if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
return true;
- // There's no need to produce frames if we are not visible.
- if (!visible_)
- return false;
-
// We need to draw a more complete frame than we did the last BeginImplFrame,
// so request another BeginImplFrame in anticipation that we will have
// additional visible tiles.
if (swap_used_incomplete_tile_)
return true;
- if (needs_animate_)
- return true;
-
- return needs_redraw_;
+ return needs_animate_ || needs_redraw_;
}
// These are cases where we are very likely to draw soon, but might not
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index e3530c8..85160ed 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -703,6 +703,7 @@ TEST(SchedulerStateMachineTest,
state.SetVisible(true);
state.SetCanDraw(false);
state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -711,6 +712,7 @@ TEST(SchedulerStateMachineTest,
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index d1d1962..2666c8c 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -53,10 +53,6 @@ void TestHooks::CreateResourceAndRasterWorkerPool(
raster_worker_pool, resource_pool, staging_resource_pool);
}
-base::TimeDelta TestHooks::LowFrequencyAnimationInterval() const {
- return base::TimeDelta::FromMilliseconds(16);
-}
-
// Adapts ThreadProxy for test. Injects test hooks for testing.
class ThreadProxyForTest : public ThreadProxy {
public:
@@ -269,10 +265,6 @@ class LayerTreeHostImplForTesting : public LayerTreeHostImpl {
test_hooks_->UpdateAnimationState(this, has_unfinished_animation);
}
- base::TimeDelta LowFrequencyAnimationInterval() const override {
- return test_hooks_->LowFrequencyAnimationInterval();
- }
-
private:
TestHooks* test_hooks_;
bool block_notify_ready_to_activate_for_testing_;
@@ -675,6 +667,7 @@ void LayerTreeTest::RunTest(bool threaded,
// Spend less time waiting for BeginFrame because the output is
// mocked out.
settings_.refresh_rate = 200.0;
+ settings_.background_animation_rate = 200.0;
settings_.impl_side_painting = impl_side_painting;
InitializeSettings(&settings_);
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 36d669c..0eb4dd2 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -84,7 +84,6 @@ class TestHooks : public AnimationDelegate {
virtual void DidDeferCommit() {}
virtual void DidSetVisibleOnImplTree(LayerTreeHostImpl* host_impl,
bool visible) {}
- virtual base::TimeDelta LowFrequencyAnimationInterval() const;
virtual void ScheduleComposite() {}
// Hooks for SchedulerClient.
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index a305dc0..b797c1c 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -173,77 +173,6 @@ size_t GetMaxStagingResourceCount() {
} // namespace
-class LayerTreeHostImplTimeSourceAdapter : public TimeSourceClient {
- public:
- static scoped_ptr<LayerTreeHostImplTimeSourceAdapter> Create(
- LayerTreeHostImpl* layer_tree_host_impl,
- scoped_refptr<DelayBasedTimeSource> time_source) {
- return make_scoped_ptr(
- new LayerTreeHostImplTimeSourceAdapter(layer_tree_host_impl,
- time_source));
- }
- ~LayerTreeHostImplTimeSourceAdapter() override {
- time_source_->SetClient(NULL);
- time_source_->SetActive(false);
- }
-
- void OnTimerTick() override {
- // In single threaded mode we attempt to simulate changing the current
- // thread by maintaining a fake thread id. When we switch from one
- // thread to another, we construct DebugScopedSetXXXThread objects that
- // update the thread id. This lets DCHECKS that ensure we're on the
- // right thread to work correctly in single threaded mode. The problem
- // here is that the timer tasks are run via the message loop, and when
- // they run, we've had no chance to construct a DebugScopedSetXXXThread
- // object. The result is that we report that we're running on the main
- // thread. In multi-threaded mode, this timer is run on the compositor
- // thread, so to keep this consistent in single-threaded mode, we'll
- // construct a DebugScopedSetImplThread object. There is no need to do
- // this in multi-threaded mode since the real thread id's will be
- // correct. In fact, setting fake thread id's interferes with the real
- // thread id's and causes breakage.
- scoped_ptr<DebugScopedSetImplThread> set_impl_thread;
- if (!layer_tree_host_impl_->proxy()->HasImplThread()) {
- set_impl_thread.reset(
- new DebugScopedSetImplThread(layer_tree_host_impl_->proxy()));
- }
-
- layer_tree_host_impl_->Animate(
- layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking(true);
- bool start_ready_animations = true;
- layer_tree_host_impl_->UpdateAnimationState(start_ready_animations);
-
- if (layer_tree_host_impl_->pending_tree()) {
- layer_tree_host_impl_->pending_tree()->UpdateDrawProperties();
- layer_tree_host_impl_->ManageTiles();
- }
-
- layer_tree_host_impl_->ResetCurrentBeginFrameArgsForNextFrame();
- }
-
- void SetActive(bool active) {
- if (active != time_source_->Active())
- time_source_->SetActive(active);
- }
-
- bool Active() const { return time_source_->Active(); }
-
- private:
- LayerTreeHostImplTimeSourceAdapter(
- LayerTreeHostImpl* layer_tree_host_impl,
- scoped_refptr<DelayBasedTimeSource> time_source)
- : layer_tree_host_impl_(layer_tree_host_impl),
- time_source_(time_source) {
- time_source_->SetClient(this);
- }
-
- LayerTreeHostImpl* layer_tree_host_impl_;
- scoped_refptr<DelayBasedTimeSource> time_source_;
-
- DISALLOW_COPY_AND_ASSIGN(LayerTreeHostImplTimeSourceAdapter);
-};
-
LayerTreeHostImpl::FrameData::FrameData()
: contains_incomplete_tile(false), has_no_damage(false) {}
@@ -974,28 +903,6 @@ void LayerTreeHostImpl::MainThreadHasStoppedFlinging() {
input_handler_client_->MainThreadHasStoppedFlinging();
}
-void LayerTreeHostImpl::UpdateBackgroundAnimateTicking(
- bool should_background_tick) {
- DCHECK(proxy_->IsImplThread());
- if (should_background_tick)
- DCHECK(active_tree_->root_layer());
-
- bool enabled = should_background_tick && needs_animate_layers();
-
- // Lazily create the time_source adapter so that we can vary the interval for
- // testing.
- if (!time_source_client_adapter_) {
- time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create(
- this,
- DelayBasedTimeSource::Create(
- LowFrequencyAnimationInterval(),
- proxy_->HasImplThread() ? proxy_->ImplThreadTaskRunner()
- : proxy_->MainThreadTaskRunner()));
- }
-
- time_source_client_adapter_->SetActive(enabled);
-}
-
void LayerTreeHostImpl::DidAnimateScrollOffset() {
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
@@ -1888,9 +1795,6 @@ void LayerTreeHostImpl::ActivateSyncTree() {
stats.draw_duration.GetLastTimeDelta());
}
- if (time_source_client_adapter_ && time_source_client_adapter_->Active())
- DCHECK(active_tree_->root_layer());
-
scoped_ptr<PageScaleAnimation> page_scale_animation =
active_tree_->TakePageScaleAnimation();
if (page_scale_animation) {
@@ -3195,10 +3099,8 @@ void LayerTreeHostImpl::ActivateAnimations() {
iter != copy.end();
++iter)
(*iter).second->ActivateAnimations();
-}
-base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
- return base::TimeDelta::FromSeconds(1);
+ SetNeedsAnimate();
}
std::string LayerTreeHostImpl::LayerTreeAsJson() const {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 2309ef7..6e860bc 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -45,7 +45,6 @@ class DebugRectHistory;
class EvictionTilePriorityQueue;
class FrameRateCounter;
class LayerImpl;
-class LayerTreeHostImplTimeSourceAdapter;
class LayerTreeImpl;
class MemoryHistory;
class PageScaleAnimation;
@@ -189,7 +188,6 @@ class CC_EXPORT LayerTreeHostImpl
virtual void UpdateAnimationState(bool start_ready_animations);
void ActivateAnimations();
void MainThreadHasStoppedFlinging();
- void UpdateBackgroundAnimateTicking(bool should_background_tick);
void DidAnimateScrollOffset();
void SetViewportDamage(const gfx::Rect& damage_rect);
@@ -330,6 +328,8 @@ class CC_EXPORT LayerTreeHostImpl
virtual void SetVisible(bool visible);
bool visible() const { return visible_; }
+ bool AnimationsAreVisible() { return visible() && CanDraw(); }
+
void SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); }
void SetNeedsRedraw();
@@ -507,8 +507,6 @@ class CC_EXPORT LayerTreeHostImpl
// Virtual for testing.
virtual void AnimateLayers(base::TimeTicks monotonic_time);
- virtual base::TimeDelta LowFrequencyAnimationInterval() const;
-
const AnimationRegistrar::AnimationControllerMap&
active_animation_controllers() const {
return animation_registrar_->active_animation_controllers();
@@ -647,9 +645,6 @@ class CC_EXPORT LayerTreeHostImpl
scoped_ptr<PageScaleAnimation> page_scale_animation_;
- // This is used for ticking animations slowly when hidden.
- scoped_ptr<LayerTreeHostImplTimeSourceAdapter> time_source_client_adapter_;
-
scoped_ptr<FrameRateCounter> fps_counter_;
scoped_ptr<PaintTimeCounter> paint_time_counter_;
scoped_ptr<MemoryHistory> memory_history_;
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index cfd8a14..470be01 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -348,8 +348,9 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
: active_tree_was_animated_(false) {}
- base::TimeDelta LowFrequencyAnimationInterval() const override {
- return base::TimeDelta::FromMilliseconds(4);
+ base::TimeDelta BackgroundAnimationInterval(LayerTreeHostImpl* host_impl) {
+ return base::TimeDelta::FromSecondsD(
+ 1.0 / host_impl->settings().background_animation_rate);
}
void BeginTest() override {
@@ -409,10 +410,9 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
FROM_HERE,
base::Bind(
&LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
- UnblockActivations,
- base::Unretained(this),
- host_impl),
- 4 * LowFrequencyAnimationInterval());
+ UnblockActivations,
+ base::Unretained(this), host_impl),
+ 4 * BackgroundAnimationInterval(host_impl));
}
}
@@ -447,10 +447,9 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
FROM_HERE,
base::Bind(
&LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
- InitiateNextCommit,
- base::Unretained(this),
- host_impl),
- 4 * LowFrequencyAnimationInterval());
+ InitiateNextCommit,
+ base::Unretained(this), host_impl),
+ 4 * BackgroundAnimationInterval(host_impl));
}
}
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index c9763a5..d81fa84 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -48,6 +48,7 @@ LayerTreeSettings::LayerTreeSettings()
top_controls_show_threshold(0.5f),
top_controls_hide_threshold(0.5f),
refresh_rate(60.0),
+ background_animation_rate(1.0),
max_partial_texture_updates(std::numeric_limits<size_t>::max()),
default_tile_size(gfx::Size(256, 256)),
max_untiled_layer_size(gfx::Size(512, 512)),
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index c5f08e9..53c9932 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -59,6 +59,7 @@ class CC_EXPORT LayerTreeSettings {
float top_controls_show_threshold;
float top_controls_hide_threshold;
double refresh_rate;
+ double background_animation_rate;
size_t max_partial_texture_updates;
gfx::Size default_tile_size;
gfx::Size max_untiled_layer_size;
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 439304a..94a6f28 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -101,7 +101,6 @@ void SingleThreadProxy::SetVisible(bool visible) {
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->SetVisible(layer_tree_host_impl_->visible());
// Changing visibility could change ShouldComposite().
- UpdateBackgroundAnimateTicking();
}
void SingleThreadProxy::RequestNewOutputSurface() {
@@ -161,6 +160,24 @@ void SingleThreadProxy::SetNeedsUpdateLayers() {
SetNeedsCommit();
}
+void SingleThreadProxy::DoAnimate() {
+ // Don't animate if there is no root layer.
+ // TODO(mithro): Both Animate and UpdateAnimationState already have a
+ // "!active_tree_->root_layer()" check?
+ if (!layer_tree_host_impl_->active_tree()->root_layer()) {
+ return;
+ }
+
+ layer_tree_host_impl_->Animate(
+ layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
+
+ // If animations are not visible, update the animation state now as it
+ // won't happen in DoComposite.
+ if (!layer_tree_host_impl_->AnimationsAreVisible()) {
+ layer_tree_host_impl_->UpdateAnimationState(true);
+ }
+}
+
void SingleThreadProxy::DoCommit() {
TRACE_EVENT0("cc", "SingleThreadProxy::DoCommit");
DCHECK(Proxy::IsMainThread());
@@ -202,8 +219,6 @@ void SingleThreadProxy::DoCommit() {
layer_tree_host_impl_->CommitComplete();
- UpdateBackgroundAnimateTicking();
-
#if DCHECK_IS_ON
// In the single-threaded case, the scale and scroll deltas should never be
// touched on the impl layer tree.
@@ -322,7 +337,6 @@ void SingleThreadProxy::OnCanDrawStateChanged(bool can_draw) {
TRACE_EVENT1(
"cc", "SingleThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
DCHECK(Proxy::IsImplThread());
- UpdateBackgroundAnimateTicking();
if (scheduler_on_impl_thread_)
scheduler_on_impl_thread_->SetCanDraw(can_draw);
}
@@ -341,7 +355,9 @@ void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
}
void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
- SetNeedsRedrawOnImplThread();
+ client_->ScheduleComposite();
+ if (scheduler_on_impl_thread_)
+ scheduler_on_impl_thread_->SetNeedsAnimate();
}
void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
@@ -414,7 +430,6 @@ void SingleThreadProxy::DidActivateSyncTree() {
weak_factory_.GetWeakPtr()));
}
- UpdateBackgroundAnimateTicking();
timing_history_.DidActivateSyncTree();
}
@@ -492,6 +507,8 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
}
+ DoAnimate();
+
LayerTreeHostImpl::FrameData frame;
DoComposite(frame_begin_time, &frame);
@@ -533,12 +550,6 @@ bool SingleThreadProxy::ShouldComposite() const {
layer_tree_host_impl_->CanDraw();
}
-void SingleThreadProxy::UpdateBackgroundAnimateTicking() {
- DCHECK(Proxy::IsImplThread());
- layer_tree_host_impl_->UpdateBackgroundAnimateTicking(
- !ShouldComposite() && layer_tree_host_impl_->active_tree()->root_layer());
-}
-
void SingleThreadProxy::ScheduleRequestNewOutputSurface() {
if (output_surface_creation_callback_.IsCancelled() &&
!output_surface_creation_requested_) {
@@ -566,16 +577,11 @@ DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time,
// DrawLayers() depends on the result of PrepareToDraw(), it is guarded on
// CanDraw() as well.
if (!ShouldComposite()) {
- UpdateBackgroundAnimateTicking();
return DRAW_ABORTED_CANT_DRAW;
}
timing_history_.DidStartDrawing();
- layer_tree_host_impl_->Animate(
- layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
- UpdateBackgroundAnimateTicking();
-
draw_result = layer_tree_host_impl_->PrepareToDraw(frame);
draw_frame = draw_result == DRAW_SUCCESS;
if (draw_frame)
@@ -736,8 +742,8 @@ void SingleThreadProxy::ScheduledActionCommit() {
void SingleThreadProxy::ScheduledActionAnimate() {
TRACE_EVENT0("cc", "ScheduledActionAnimate");
- layer_tree_host_impl_->Animate(
- layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
+ DebugScopedSetImplThread impl(this);
+ DoAnimate();
}
void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 5b3766b..1e76857 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -118,6 +118,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void BeginMainFrame();
void BeginMainFrameAbortedOnImplThread();
+ void DoAnimate();
void DoBeginMainFrame(const BeginFrameArgs& begin_frame_args);
void DoCommit();
DrawResult DoComposite(base::TimeTicks frame_begin_time,
@@ -127,7 +128,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void CommitComplete();
bool ShouldComposite() const;
- void UpdateBackgroundAnimateTicking();
void ScheduleRequestNewOutputSurface();
// Accessed on main thread only.
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 37830f6..65e8dd2 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -176,18 +176,9 @@ void ThreadProxy::SetVisibleOnImplThread(CompletionEvent* completion,
TRACE_EVENT0("cc", "ThreadProxy::SetVisibleOnImplThread");
impl().layer_tree_host_impl->SetVisible(visible);
impl().scheduler->SetVisible(visible);
- UpdateBackgroundAnimateTicking();
completion->Signal();
}
-void ThreadProxy::UpdateBackgroundAnimateTicking() {
- bool should_background_tick =
- !impl().scheduler->WillDrawIfNeeded() &&
- impl().layer_tree_host_impl->active_tree()->root_layer();
- impl().layer_tree_host_impl->UpdateBackgroundAnimateTicking(
- should_background_tick);
-}
-
void ThreadProxy::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "ThreadProxy::DidLoseOutputSurface");
DCHECK(IsMainThread());
@@ -358,7 +349,6 @@ void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
"cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
DCHECK(IsImplThread());
impl().scheduler->SetCanDraw(can_draw);
- UpdateBackgroundAnimateTicking();
}
void ThreadProxy::NotifyReadyToActivate() {
@@ -927,9 +917,22 @@ void ThreadProxy::ScheduledActionAnimate() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate");
DCHECK(IsImplThread());
+ // Don't animate if there is no root layer.
+ // TODO(mithro): Both Animate and UpdateAnimationState already have a
+ // "!active_tree_->root_layer()" check?
+ if (!impl().layer_tree_host_impl->active_tree()->root_layer()) {
+ return;
+ }
+
impl().animation_time =
impl().layer_tree_host_impl->CurrentBeginFrameArgs().frame_time;
impl().layer_tree_host_impl->Animate(impl().animation_time);
+
+ // If animations are not visible, update the state now as
+ // ScheduledActionDrawAndSwapIfPossible will never be called.
+ if (!impl().layer_tree_host_impl->AnimationsAreVisible()) {
+ impl().layer_tree_host_impl->UpdateAnimationState(true);
+ }
}
void ThreadProxy::ScheduledActionCommit() {
@@ -973,8 +976,6 @@ void ThreadProxy::ScheduledActionCommit() {
SetInputThrottledUntilCommitOnImplThread(false);
- UpdateBackgroundAnimateTicking();
-
impl().next_frame_is_newly_committed_frame = true;
impl().timing_history.DidCommit();
@@ -1352,8 +1353,6 @@ void ThreadProxy::DidActivateSyncTree() {
impl().completion_event_for_commit_held_on_tree_activation = NULL;
}
- UpdateBackgroundAnimateTicking();
-
impl().timing_history.DidActivateSyncTree();
}
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index 2f3e7c5..f10e4ba 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -253,7 +253,6 @@ class CC_EXPORT ThreadProxy : public Proxy,
void InitializeImplOnImplThread(CompletionEvent* completion);
void SetLayerTreeHostClientReadyOnImplThread();
void SetVisibleOnImplThread(CompletionEvent* completion, bool visible);
- void UpdateBackgroundAnimateTicking();
void HasInitializedOutputSurfaceOnImplThread(
CompletionEvent* completion,
bool* has_initialized_output_surface);