Index: cc/scheduler/scheduler.cc |
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc |
index 88c8c74f701d2f4aa0a8980cff8b01f2a21335ea..f042b38fff4e1fcacb782067b25a00ac100627fc 100644 |
--- a/cc/scheduler/scheduler.cc |
+++ b/cc/scheduler/scheduler.cc |
@@ -11,64 +11,11 @@ |
#include "cc/debug/devtools_instrumentation.h" |
#include "cc/debug/traced_value.h" |
#include "cc/scheduler/delay_based_time_source.h" |
+#include "cc/scheduler/frame_source.h" |
#include "ui/gfx/frame_time.h" |
namespace cc { |
-class SyntheticBeginFrameSource : public TimeSourceClient { |
- public: |
- SyntheticBeginFrameSource(Scheduler* scheduler, |
- base::SingleThreadTaskRunner* task_runner) |
- : scheduler_(scheduler) { |
- if (gfx::FrameTime::TimestampsAreHighRes()) { |
- time_source_ = DelayBasedTimeSourceHighRes::Create( |
- scheduler_->VSyncInterval(), task_runner); |
- } else { |
- time_source_ = DelayBasedTimeSource::Create(scheduler_->VSyncInterval(), |
- task_runner); |
- } |
- time_source_->SetClient(this); |
- } |
- |
- virtual ~SyntheticBeginFrameSource() {} |
- |
- // Updates the phase and frequency of the timer. |
- void CommitVSyncParameters(base::TimeTicks timebase, |
- base::TimeDelta interval) { |
- time_source_->SetTimebaseAndInterval(timebase, interval); |
- } |
- |
- // Activates future BeginFrames and, if activating, pushes the most |
- // recently missed BeginFrame to the back of a retroactive queue. |
- void SetNeedsBeginFrame(bool needs_begin_frame, |
- std::deque<BeginFrameArgs>* begin_retro_frame_args) { |
- base::TimeTicks missed_tick_time = |
- time_source_->SetActive(needs_begin_frame); |
- if (!missed_tick_time.is_null()) { |
- begin_retro_frame_args->push_back( |
- CreateSyntheticBeginFrameArgs(missed_tick_time)); |
- } |
- } |
- |
- // TimeSourceClient implementation of OnTimerTick triggers a BeginFrame. |
- virtual void OnTimerTick() OVERRIDE { |
- BeginFrameArgs begin_frame_args( |
- CreateSyntheticBeginFrameArgs(time_source_->LastTickTime())); |
- scheduler_->BeginFrame(begin_frame_args); |
- } |
- |
- private: |
- BeginFrameArgs CreateSyntheticBeginFrameArgs(base::TimeTicks frame_time) { |
- base::TimeTicks deadline = |
- time_source_->NextTickTime() - scheduler_->EstimatedParentDrawTime(); |
- return BeginFrameArgs::Create( |
- frame_time, deadline, scheduler_->VSyncInterval()); |
- } |
- |
- Scheduler* scheduler_; |
- scoped_refptr<TimeSource> time_source_; |
-}; |
- |
Scheduler::Scheduler( |
SchedulerClient* client, |
const SchedulerSettings& scheduler_settings, |
@@ -78,7 +25,6 @@ Scheduler::Scheduler( |
client_(client), |
layer_tree_host_id_(layer_tree_host_id), |
impl_task_runner_(impl_task_runner), |
- vsync_interval_(BeginFrameArgs::DefaultInterval()), |
last_set_needs_begin_frame_(false), |
begin_unthrottled_frame_posted_(false), |
begin_retro_frame_posted_(false), |
@@ -109,16 +55,7 @@ Scheduler::Scheduler( |
} |
Scheduler::~Scheduler() { |
- if (synthetic_begin_frame_source_) { |
- synthetic_begin_frame_source_->SetNeedsBeginFrame(false, |
- &begin_retro_frame_args_); |
- } |
-} |
- |
-void Scheduler::SetupSyntheticBeginFrames() { |
- DCHECK(!synthetic_begin_frame_source_); |
- synthetic_begin_frame_source_.reset( |
- new SyntheticBeginFrameSource(this, impl_task_runner_.get())); |
+ frame_source_->SetNeedsBeginFrame(false); |
} |
void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
@@ -126,9 +63,8 @@ void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, |
// TODO(brianderson): We should not be receiving 0 intervals. |
if (interval == base::TimeDelta()) |
interval = BeginFrameArgs::DefaultInterval(); |
- vsync_interval_ = interval; |
if (!settings_.begin_frame_scheduling_enabled) |
- synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); |
+ frame_source_->UpdateFrameSource(timebase, interval); |
} |
void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { |
@@ -268,78 +204,10 @@ base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
void Scheduler::SetupNextBeginFrameIfNeeded() { |
bool needs_begin_frame = state_machine_.BeginFrameNeeded(); |
- |
- if (settings_.throttle_frame_production) { |
- SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame); |
- } else { |
- SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame); |
- } |
+ frame_source_->SetNeedsBeginFrame(needs_begin_frame); |
SetupPollingMechanisms(needs_begin_frame); |
} |
-// When we are throttling frame production, we request BeginFrames |
-// from the OutputSurface. |
-void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingEnabled( |
- bool needs_begin_frame) { |
- bool at_end_of_deadline = |
- state_machine_.begin_impl_frame_state() == |
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
- |
- bool should_call_set_needs_begin_frame = |
- // Always request the BeginFrame immediately if it wasn't needed before. |
- (needs_begin_frame && !last_set_needs_begin_frame_) || |
- // Only stop requesting BeginFrames after a deadline. |
- (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline); |
- |
- if (should_call_set_needs_begin_frame) { |
- if (settings_.begin_frame_scheduling_enabled) { |
- client_->SetNeedsBeginFrame(needs_begin_frame); |
- } else { |
- synthetic_begin_frame_source_->SetNeedsBeginFrame( |
- needs_begin_frame, &begin_retro_frame_args_); |
- } |
- last_set_needs_begin_frame_ = needs_begin_frame; |
- } |
- |
- PostBeginRetroFrameIfNeeded(); |
-} |
- |
-// When we aren't throttling frame production, we initiate a BeginFrame |
-// as soon as one is needed. |
-void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled( |
- bool needs_begin_frame) { |
- last_set_needs_begin_frame_ = needs_begin_frame; |
- |
- if (!needs_begin_frame || begin_unthrottled_frame_posted_) |
- return; |
- |
- if (state_machine_.begin_impl_frame_state() != |
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE && |
- state_machine_.begin_impl_frame_state() != |
- SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { |
- return; |
- } |
- |
- begin_unthrottled_frame_posted_ = true; |
- impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); |
-} |
- |
-// BeginUnthrottledFrame is used when we aren't throttling frame production. |
-// This will usually be because VSync is disabled. |
-void Scheduler::BeginUnthrottledFrame() { |
- DCHECK(!settings_.throttle_frame_production); |
- DCHECK(begin_retro_frame_args_.empty()); |
- |
- base::TimeTicks now = gfx::FrameTime::Now(); |
- base::TimeTicks deadline = now + vsync_interval_; |
- |
- BeginFrameArgs begin_frame_args = |
- BeginFrameArgs::Create(now, deadline, vsync_interval_); |
- BeginImplFrame(begin_frame_args); |
- |
- begin_unthrottled_frame_posted_ = false; |
-} |
- |
// We may need to poll when we can't rely on BeginFrame to advance certain |
// state or to avoid deadlock. |
void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { |
@@ -395,6 +263,14 @@ void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { |
// a BeginRetroFrame. |
void Scheduler::BeginFrame(const BeginFrameArgs& args) { |
TRACE_EVENT1("cc", "Scheduler::BeginFrame", "frame_time", args.frame_time); |
+ |
+ clock_source->BeginFrame(this, args); |
+} |
+ |
+void Scheduler::BeginFrameOnScheduler(const BeginFrameArgs& args) { |
+ TRACE_EVENT1( |
+ "cc", "Scheduler::BeginFrameOnScheduler", "frame_time", args.frame_time); |
+ |
DCHECK(settings_.throttle_frame_production); |
bool should_defer_begin_frame; |
@@ -690,13 +566,12 @@ bool Scheduler::WillDrawIfNeeded() const { |
scoped_ptr<base::Value> Scheduler::StateAsValue() const { |
scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
state->Set("state_machine", state_machine_.AsValue().release()); |
+ state->Set("frame_source", frame_source_.AsValue().release()); |
scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); |
scheduler_state->SetDouble( |
"time_until_anticipated_draw_time_ms", |
(AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); |
- scheduler_state->SetDouble("vsync_interval_ms", |
- vsync_interval_.InMillisecondsF()); |
scheduler_state->SetDouble("estimated_parent_draw_time_ms", |
estimated_parent_draw_time_.InMillisecondsF()); |
scheduler_state->SetBoolean("last_set_needs_begin_frame_", |