diff options
Diffstat (limited to 'cc/scheduler/scheduler.cc')
-rw-r--r-- | cc/scheduler/scheduler.cc | 125 |
1 files changed, 57 insertions, 68 deletions
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc index 7110bff..d308b0d 100644 --- a/cc/scheduler/scheduler.cc +++ b/cc/scheduler/scheduler.cc @@ -7,29 +7,23 @@ #include "base/auto_reset.h" #include "base/debug/trace_event.h" #include "base/logging.h" -#include "cc/base/thread.h" namespace cc { Scheduler::Scheduler(SchedulerClient* client, + scoped_ptr<FrameRateController> frame_rate_controller, const SchedulerSettings& scheduler_settings) : settings_(scheduler_settings), client_(client), - weak_factory_(this), - last_set_needs_begin_frame_(false), - has_pending_begin_frame_(false), - last_begin_frame_time_(base::TimeTicks()), - // TODO(brianderson): Pass with BeginFrame in the near future. - interval_(base::TimeDelta::FromMicroseconds(16666)), + frame_rate_controller_(frame_rate_controller.Pass()), state_machine_(scheduler_settings), inside_process_scheduled_actions_(false) { DCHECK(client_); + frame_rate_controller_->SetClient(this); DCHECK(!state_machine_.BeginFrameNeededByImplThread()); } -Scheduler::~Scheduler() { - client_->SetNeedsBeginFrameOnImplThread(false); -} +Scheduler::~Scheduler() { frame_rate_controller_->SetActive(false); } void Scheduler::SetCanStart() { state_machine_.SetCanStart(); @@ -94,6 +88,23 @@ void Scheduler::BeginFrameAbortedByMainThread() { ProcessScheduledActions(); } +void Scheduler::SetMaxFramesPending(int max_frames_pending) { + frame_rate_controller_->SetMaxFramesPending(max_frames_pending); +} + +int Scheduler::MaxFramesPending() const { + return frame_rate_controller_->MaxFramesPending(); +} + +int Scheduler::NumFramesPendingForTesting() const { + return frame_rate_controller_->NumFramesPendingForTesting(); +} + +void Scheduler::DidSwapBuffersComplete() { + TRACE_EVENT0("cc", "Scheduler::DidSwapBuffersComplete"); + frame_rate_controller_->DidSwapBuffersComplete(); +} + void Scheduler::DidLoseOutputSurface() { TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); state_machine_.DidLoseOutputSurface(); @@ -102,69 +113,31 @@ void Scheduler::DidLoseOutputSurface() { void Scheduler::DidCreateAndInitializeOutputSurface() { TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); + frame_rate_controller_->DidAbortAllPendingFrames(); state_machine_.DidCreateAndInitializeOutputSurface(); - has_pending_begin_frame_ = false; - last_set_needs_begin_frame_ = false; ProcessScheduledActions(); } +void Scheduler::SetTimebaseAndInterval(base::TimeTicks timebase, + base::TimeDelta interval) { + frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); +} + base::TimeTicks Scheduler::AnticipatedDrawTime() { - TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); - base::TimeTicks now = base::TimeTicks::Now(); - int64 intervals = ((now - last_begin_frame_time_) / interval_) + 1; - return last_begin_frame_time_ + (interval_ * intervals); + return frame_rate_controller_->NextTickTime(); } base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() { - return last_begin_frame_time_; -} - -void Scheduler::SetupNextBeginFrameIfNeeded() { - // Determine if we need BeginFrame notifications. - // If we do, always request the BeginFrame immediately. - // If not, only disable on the next BeginFrame to avoid unnecessary toggles. - // The synchronous renderer compositor requires immediate disables though. - bool needs_begin_frame = state_machine_.BeginFrameNeededByImplThread(); - if ((needs_begin_frame || - state_machine_.inside_begin_frame() || - settings_.using_synchronous_renderer_compositor) && - (needs_begin_frame != last_set_needs_begin_frame_)) { - client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); - last_set_needs_begin_frame_ = needs_begin_frame; - } - - // Request another BeginFrame if we haven't drawn for now until we have - // deadlines implemented. - if (state_machine_.inside_begin_frame() && has_pending_begin_frame_) { - has_pending_begin_frame_ = false; - client_->SetNeedsBeginFrameOnImplThread(true); - } + return frame_rate_controller_->LastTickTime(); } -void Scheduler::BeginFrame(base::TimeTicks frame_time) { - TRACE_EVENT0("cc", "Scheduler::BeginFrame"); - DCHECK(!has_pending_begin_frame_); - has_pending_begin_frame_ = true; - last_begin_frame_time_ = frame_time; - state_machine_.DidEnterBeginFrame(); - state_machine_.SetFrameTime(frame_time); +void Scheduler::BeginFrame(bool throttled) { + TRACE_EVENT1("cc", "Scheduler::BeginFrame", "throttled", throttled); + if (!throttled) + state_machine_.DidEnterBeginFrame(); ProcessScheduledActions(); - state_machine_.DidLeaveBeginFrame(); -} - -void Scheduler::DrawAndSwapIfPossible() { - ScheduledActionDrawAndSwapResult result = - client_->ScheduledActionDrawAndSwapIfPossible(); - state_machine_.DidDrawIfPossibleCompleted(result.did_draw); - if (result.did_swap) - has_pending_begin_frame_ = false; -} - -void Scheduler::DrawAndSwapForced() { - ScheduledActionDrawAndSwapResult result = - client_->ScheduledActionDrawAndSwapForced(); - if (result.did_swap) - has_pending_begin_frame_ = false; + if (!throttled) + state_machine_.DidLeaveBeginFrame(); } void Scheduler::ProcessScheduledActions() { @@ -178,6 +151,9 @@ void Scheduler::ProcessScheduledActions() { SchedulerStateMachine::Action action = state_machine_.NextAction(); while (action != SchedulerStateMachine::ACTION_NONE) { state_machine_.UpdateState(action); + TRACE_EVENT1( + "cc", "Scheduler::ProcessScheduledActions()", "action", action); + switch (action) { case SchedulerStateMachine::ACTION_NONE: break; @@ -193,12 +169,23 @@ void Scheduler::ProcessScheduledActions() { case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: client_->ScheduledActionActivatePendingTreeIfNeeded(); break; - case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: - DrawAndSwapIfPossible(); + case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: { + frame_rate_controller_->DidSwapBuffers(); + ScheduledActionDrawAndSwapResult result = + client_->ScheduledActionDrawAndSwapIfPossible(); + state_machine_.DidDrawIfPossibleCompleted(result.did_draw); + if (!result.did_swap) + frame_rate_controller_->DidSwapBuffersComplete(); break; - case SchedulerStateMachine::ACTION_DRAW_FORCED: - DrawAndSwapForced(); + } + case SchedulerStateMachine::ACTION_DRAW_FORCED: { + frame_rate_controller_->DidSwapBuffers(); + ScheduledActionDrawAndSwapResult result = + client_->ScheduledActionDrawAndSwapForced(); + if (!result.did_swap) + frame_rate_controller_->DidSwapBuffersComplete(); break; + } case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: client_->ScheduledActionBeginOutputSurfaceCreation(); break; @@ -209,8 +196,10 @@ void Scheduler::ProcessScheduledActions() { action = state_machine_.NextAction(); } - SetupNextBeginFrameIfNeeded(); - client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); + // Activate or deactivate the frame rate controller. + frame_rate_controller_->SetActive( + state_machine_.BeginFrameNeededByImplThread()); + client_->DidAnticipatedDrawTimeChange(frame_rate_controller_->NextTickTime()); } bool Scheduler::WillDrawIfNeeded() const { |