summaryrefslogtreecommitdiffstats
path: root/cc
diff options
context:
space:
mode:
authormithro <mithro@mithis.com>2014-11-04 23:41:48 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-05 07:43:37 +0000
commit8b794fe7e4eda70ec746f4e1ff15c3c3aec50ff3 (patch)
treeff6aa64cd3f8821ba98502d00601125f284c2244 /cc
parent683ede85fb6da926933fcb91a6efd57f84ac0204 (diff)
downloadchromium_src-8b794fe7e4eda70ec746f4e1ff15c3c3aec50ff3.zip
chromium_src-8b794fe7e4eda70ec746f4e1ff15c3c3aec50ff3.tar.gz
chromium_src-8b794fe7e4eda70ec746f4e1ff15c3c3aec50ff3.tar.bz2
Revert of Moving background animation ticking from LayerTreeHostImpl into the Scheduler. (patchset #9 id:460001 of https://codereview.chromium.org/595973002/)
Reason for revert: Reverting because of failure here http://build.chromium.org/p/chromium.chromiumos/builders/Linux%20ChromiumOS%20Tests%20%28dbg%29%281%29 Will investigate tomorrow. Original issue's description: > 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} TBR=danakj@chromium.org,brianderson@chromium.org,skyostil@chromium.org,ajuma@chromium.org NOTREECHECKS=true NOTRY=true BUG=345459 Review URL: https://codereview.chromium.org/698413002 Cr-Commit-Position: refs/heads/master@{#302763}
Diffstat (limited to 'cc')
-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
16 files changed, 180 insertions, 70 deletions
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 4c2316f..88c27c1 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(),
- scheduler->settings_.background_frame_interval);
+ SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
+ scheduler->Now(),
+ base::TimeDelta::FromSeconds(1));
return scheduler->background_frame_source_internal_.get();
}
diff --git a/cc/scheduler/scheduler_settings.cc b/cc/scheduler/scheduler_settings.cc
index 95294ad..ab9add0 100644
--- a/cc/scheduler/scheduler_settings.cc
+++ b/cc/scheduler/scheduler_settings.cc
@@ -17,8 +17,7 @@ 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),
- background_frame_interval(base::TimeDelta::FromSeconds(1)) {
+ disable_hi_res_timer_tasks_on_battery(false) {
}
SchedulerSettings::SchedulerSettings(const LayerTreeSettings& settings)
@@ -34,9 +33,7 @@ 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),
- background_frame_interval(base::TimeDelta::FromSecondsD(
- 1.0 / settings.background_animation_rate)) {
+ settings.disable_hi_res_timer_tasks_on_battery) {
}
SchedulerSettings::~SchedulerSettings() {}
@@ -59,8 +56,6 @@ 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 561d265..8607991 100644
--- a/cc/scheduler/scheduler_settings.h
+++ b/cc/scheduler/scheduler_settings.h
@@ -6,7 +6,6 @@
#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"
@@ -34,8 +33,6 @@ 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 94016f3..2b8210d 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -423,6 +423,9 @@ 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;
@@ -762,18 +765,29 @@ 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;
- return needs_animate_ || needs_redraw_;
+ if (needs_animate_)
+ return true;
+
+ return 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 85160ed..e3530c8 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -703,7 +703,6 @@ 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);
@@ -712,7 +711,6 @@ 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 2666c8c..d1d1962 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -53,6 +53,10 @@ 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:
@@ -265,6 +269,10 @@ 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_;
@@ -667,7 +675,6 @@ 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 0eb4dd2..36d669c 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -84,6 +84,7 @@ 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 e266980..20f0c6d 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -167,6 +167,77 @@ 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) {}
@@ -897,6 +968,28 @@ 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();
@@ -1788,6 +1881,9 @@ void LayerTreeHostImpl::ActivateSyncTree() {
stats.impl_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) {
@@ -3095,8 +3191,10 @@ void LayerTreeHostImpl::ActivateAnimations() {
iter != copy.end();
++iter)
(*iter).second->ActivateAnimations();
+}
- SetNeedsAnimate();
+base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
+ return base::TimeDelta::FromSeconds(1);
}
std::string LayerTreeHostImpl::LayerTreeAsJson() const {
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index b7c0a7b..157fe00 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -45,6 +45,7 @@ class DebugRectHistory;
class EvictionTilePriorityQueue;
class FrameRateCounter;
class LayerImpl;
+class LayerTreeHostImplTimeSourceAdapter;
class LayerTreeImpl;
class MemoryHistory;
class PageScaleAnimation;
@@ -187,6 +188,7 @@ 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);
@@ -327,8 +329,6 @@ 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();
@@ -506,6 +506,8 @@ 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();
@@ -644,6 +646,9 @@ 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 470be01..cfd8a14 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -348,9 +348,8 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree()
: active_tree_was_animated_(false) {}
- base::TimeDelta BackgroundAnimationInterval(LayerTreeHostImpl* host_impl) {
- return base::TimeDelta::FromSecondsD(
- 1.0 / host_impl->settings().background_animation_rate);
+ base::TimeDelta LowFrequencyAnimationInterval() const override {
+ return base::TimeDelta::FromMilliseconds(4);
}
void BeginTest() override {
@@ -410,9 +409,10 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
FROM_HERE,
base::Bind(
&LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
- UnblockActivations,
- base::Unretained(this), host_impl),
- 4 * BackgroundAnimationInterval(host_impl));
+ UnblockActivations,
+ base::Unretained(this),
+ host_impl),
+ 4 * LowFrequencyAnimationInterval());
}
}
@@ -447,9 +447,10 @@ class LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree
FROM_HERE,
base::Bind(
&LayerTreeHostAnimationTestNoBackgroundTickingWithoutActiveTree::
- InitiateNextCommit,
- base::Unretained(this), host_impl),
- 4 * BackgroundAnimationInterval(host_impl));
+ InitiateNextCommit,
+ base::Unretained(this),
+ host_impl),
+ 4 * LowFrequencyAnimationInterval());
}
}
diff --git a/cc/trees/layer_tree_settings.cc b/cc/trees/layer_tree_settings.cc
index 45911ee..1d5cf1b 100644
--- a/cc/trees/layer_tree_settings.cc
+++ b/cc/trees/layer_tree_settings.cc
@@ -47,7 +47,6 @@ 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 8c11655..74a3b0c 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -58,7 +58,6 @@ 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 1305046..1af657a 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -101,6 +101,7 @@ 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() {
@@ -160,24 +161,6 @@ 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());
@@ -219,6 +202,8 @@ 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.
@@ -343,6 +328,7 @@ 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);
}
@@ -361,9 +347,7 @@ void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
}
void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
- client_->ScheduleComposite();
- if (scheduler_on_impl_thread_)
- scheduler_on_impl_thread_->SetNeedsAnimate();
+ SetNeedsRedrawOnImplThread();
}
void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
@@ -436,6 +420,7 @@ void SingleThreadProxy::DidActivateSyncTree() {
weak_factory_.GetWeakPtr()));
}
+ UpdateBackgroundAnimateTicking();
timing_history_.DidActivateSyncTree();
}
@@ -513,8 +498,6 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time) {
layer_tree_host_impl_->SynchronouslyInitializeAllTiles();
}
- DoAnimate();
-
LayerTreeHostImpl::FrameData frame;
DoComposite(frame_begin_time, &frame);
@@ -556,6 +539,12 @@ 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_) {
@@ -583,11 +572,16 @@ 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)
@@ -748,8 +742,8 @@ void SingleThreadProxy::ScheduledActionCommit() {
void SingleThreadProxy::ScheduledActionAnimate() {
TRACE_EVENT0("cc", "ScheduledActionAnimate");
- DebugScopedSetImplThread impl(this);
- DoAnimate();
+ layer_tree_host_impl_->Animate(
+ layer_tree_host_impl_->CurrentBeginFrameArgs().frame_time);
}
void SingleThreadProxy::ScheduledActionUpdateVisibleTiles() {
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index 1e76857..5b3766b 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -118,7 +118,6 @@ 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,
@@ -128,6 +127,7 @@ 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 373eec0..14e2181 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -176,9 +176,18 @@ 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());
@@ -349,6 +358,7 @@ void ThreadProxy::OnCanDrawStateChanged(bool can_draw) {
"cc", "ThreadProxy::OnCanDrawStateChanged", "can_draw", can_draw);
DCHECK(IsImplThread());
impl().scheduler->SetCanDraw(can_draw);
+ UpdateBackgroundAnimateTicking();
}
void ThreadProxy::NotifyReadyToActivate() {
@@ -923,22 +933,9 @@ 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() {
@@ -982,6 +979,8 @@ void ThreadProxy::ScheduledActionCommit() {
SetInputThrottledUntilCommitOnImplThread(false);
+ UpdateBackgroundAnimateTicking();
+
impl().next_frame_is_newly_committed_frame = true;
impl().timing_history.DidCommit();
@@ -1359,6 +1358,8 @@ 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 f10e4ba..2f3e7c5 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -253,6 +253,7 @@ 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);