1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/scheduler/scheduler.h"
7 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h"
9 #include "base/logging.h"
13 Scheduler::Scheduler(SchedulerClient
* client
,
14 scoped_ptr
<FrameRateController
> frame_rate_controller
,
15 const SchedulerSettings
& scheduler_settings
)
16 : settings_(scheduler_settings
),
18 frame_rate_controller_(frame_rate_controller
.Pass()),
19 state_machine_(scheduler_settings
),
20 inside_process_scheduled_actions_(false) {
22 frame_rate_controller_
->SetClient(this);
23 DCHECK(!state_machine_
.BeginFrameNeededByImplThread());
26 Scheduler::~Scheduler() { frame_rate_controller_
->SetActive(false); }
28 void Scheduler::SetCanStart() {
29 state_machine_
.SetCanStart();
30 ProcessScheduledActions();
33 void Scheduler::SetVisible(bool visible
) {
34 state_machine_
.SetVisible(visible
);
35 ProcessScheduledActions();
38 void Scheduler::SetCanDraw(bool can_draw
) {
39 state_machine_
.SetCanDraw(can_draw
);
40 ProcessScheduledActions();
43 void Scheduler::SetHasPendingTree(bool has_pending_tree
) {
44 state_machine_
.SetHasPendingTree(has_pending_tree
);
45 ProcessScheduledActions();
48 void Scheduler::SetNeedsCommit() {
49 state_machine_
.SetNeedsCommit();
50 ProcessScheduledActions();
53 void Scheduler::SetNeedsForcedCommit() {
54 state_machine_
.SetNeedsCommit();
55 state_machine_
.SetNeedsForcedCommit();
56 ProcessScheduledActions();
59 void Scheduler::SetNeedsRedraw() {
60 state_machine_
.SetNeedsRedraw();
61 ProcessScheduledActions();
64 void Scheduler::DidSwapUseIncompleteTile() {
65 state_machine_
.DidSwapUseIncompleteTile();
66 ProcessScheduledActions();
69 void Scheduler::SetNeedsForcedRedraw() {
70 state_machine_
.SetNeedsForcedRedraw();
71 ProcessScheduledActions();
74 void Scheduler::SetMainThreadNeedsLayerTextures() {
75 state_machine_
.SetMainThreadNeedsLayerTextures();
76 ProcessScheduledActions();
79 void Scheduler::FinishCommit() {
80 TRACE_EVENT0("cc", "Scheduler::FinishCommit");
81 state_machine_
.FinishCommit();
82 ProcessScheduledActions();
85 void Scheduler::BeginFrameAbortedByMainThread() {
86 TRACE_EVENT0("cc", "Scheduler::BeginFrameAbortedByMainThread");
87 state_machine_
.BeginFrameAbortedByMainThread();
88 ProcessScheduledActions();
91 void Scheduler::SetMaxFramesPending(int max_frames_pending
) {
92 frame_rate_controller_
->SetMaxFramesPending(max_frames_pending
);
95 int Scheduler::MaxFramesPending() const {
96 return frame_rate_controller_
->MaxFramesPending();
99 int Scheduler::NumFramesPendingForTesting() const {
100 return frame_rate_controller_
->NumFramesPendingForTesting();
103 void Scheduler::SetSwapBuffersCompleteSupported(bool supported
) {
104 frame_rate_controller_
->SetSwapBuffersCompleteSupported(supported
);
107 void Scheduler::DidSwapBuffersComplete() {
108 TRACE_EVENT0("cc", "Scheduler::DidSwapBuffersComplete");
109 frame_rate_controller_
->DidSwapBuffersComplete();
112 void Scheduler::DidLoseOutputSurface() {
113 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
114 state_machine_
.DidLoseOutputSurface();
115 ProcessScheduledActions();
118 void Scheduler::DidCreateAndInitializeOutputSurface() {
119 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
120 frame_rate_controller_
->DidAbortAllPendingFrames();
121 state_machine_
.DidCreateAndInitializeOutputSurface();
122 ProcessScheduledActions();
125 void Scheduler::SetTimebaseAndInterval(base::TimeTicks timebase
,
126 base::TimeDelta interval
) {
127 frame_rate_controller_
->SetTimebaseAndInterval(timebase
, interval
);
130 base::TimeTicks
Scheduler::AnticipatedDrawTime() {
131 return frame_rate_controller_
->NextTickTime();
134 base::TimeTicks
Scheduler::LastBeginFrameOnImplThreadTime() {
135 return frame_rate_controller_
->LastTickTime();
138 void Scheduler::BeginFrame(bool throttled
) {
139 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "throttled", throttled
);
141 state_machine_
.DidEnterBeginFrame();
142 ProcessScheduledActions();
144 state_machine_
.DidLeaveBeginFrame();
147 void Scheduler::ProcessScheduledActions() {
148 // We do not allow ProcessScheduledActions to be recursive.
149 // The top-level call will iteratively execute the next action for us anyway.
150 if (inside_process_scheduled_actions_
)
153 base::AutoReset
<bool> mark_inside(&inside_process_scheduled_actions_
, true);
155 SchedulerStateMachine::Action action
= state_machine_
.NextAction();
156 while (action
!= SchedulerStateMachine::ACTION_NONE
) {
157 state_machine_
.UpdateState(action
);
159 "cc", "Scheduler::ProcessScheduledActions()", "action", action
);
162 case SchedulerStateMachine::ACTION_NONE
:
164 case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
:
165 client_
->ScheduledActionSendBeginFrameToMainThread();
167 case SchedulerStateMachine::ACTION_COMMIT
:
168 client_
->ScheduledActionCommit();
170 case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS
:
171 client_
->ScheduledActionCheckForCompletedTileUploads();
173 case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED
:
174 client_
->ScheduledActionActivatePendingTreeIfNeeded();
176 case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
: {
177 ScheduledActionDrawAndSwapResult result
=
178 client_
->ScheduledActionDrawAndSwapIfPossible();
179 state_machine_
.DidDrawIfPossibleCompleted(result
.did_draw
);
181 frame_rate_controller_
->DidSwapBuffers();
184 case SchedulerStateMachine::ACTION_DRAW_FORCED
: {
185 ScheduledActionDrawAndSwapResult result
=
186 client_
->ScheduledActionDrawAndSwapForced();
188 frame_rate_controller_
->DidSwapBuffers();
191 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
:
192 client_
->ScheduledActionBeginOutputSurfaceCreation();
194 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD
:
195 client_
->ScheduledActionAcquireLayerTexturesForMainThread();
198 action
= state_machine_
.NextAction();
201 // Activate or deactivate the frame rate controller.
202 frame_rate_controller_
->SetActive(
203 state_machine_
.BeginFrameNeededByImplThread());
204 client_
->DidAnticipatedDrawTimeChange(frame_rate_controller_
->NextTickTime());
207 bool Scheduler::WillDrawIfNeeded() const {
208 return !state_machine_
.DrawSuspendedUntilCommit();