summaryrefslogtreecommitdiffstats
path: root/cc/scheduler/scheduler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'cc/scheduler/scheduler.cc')
-rw-r--r--cc/scheduler/scheduler.cc125
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 {