diff options
author | mithro <mithro@mithis.com> | 2014-11-04 23:41:48 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-05 07:43:37 +0000 |
commit | 8b794fe7e4eda70ec746f4e1ff15c3c3aec50ff3 (patch) | |
tree | ff6aa64cd3f8821ba98502d00601125f284c2244 | |
parent | 683ede85fb6da926933fcb91a6efd57f84ac0204 (diff) | |
download | chromium_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}
-rw-r--r-- | cc/scheduler/scheduler.cc | 6 | ||||
-rw-r--r-- | cc/scheduler/scheduler_settings.cc | 9 | ||||
-rw-r--r-- | cc/scheduler/scheduler_settings.h | 3 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine.cc | 16 | ||||
-rw-r--r-- | cc/scheduler/scheduler_state_machine_unittest.cc | 2 | ||||
-rw-r--r-- | cc/test/layer_tree_test.cc | 9 | ||||
-rw-r--r-- | cc/test/layer_tree_test.h | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.cc | 100 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_impl.h | 9 | ||||
-rw-r--r-- | cc/trees/layer_tree_host_unittest_animation.cc | 19 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.cc | 1 | ||||
-rw-r--r-- | cc/trees/layer_tree_settings.h | 1 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.cc | 44 | ||||
-rw-r--r-- | cc/trees/single_thread_proxy.h | 2 | ||||
-rw-r--r-- | cc/trees/thread_proxy.cc | 27 | ||||
-rw-r--r-- | cc/trees/thread_proxy.h | 1 |
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); |