Fix Win8 metro startup crash from window switcher button
[chromium-blink-merge.git] / cc / scheduler / scheduler.cc
blob737ffc1bb1222b2af5fec3d72e7a468abd4fa2ad
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"
11 namespace cc {
13 Scheduler::Scheduler(SchedulerClient* client,
14 scoped_ptr<FrameRateController> frame_rate_controller,
15 const SchedulerSettings& scheduler_settings)
16 : settings_(scheduler_settings),
17 client_(client),
18 frame_rate_controller_(frame_rate_controller.Pass()),
19 state_machine_(scheduler_settings),
20 inside_process_scheduled_actions_(false) {
21 DCHECK(client_);
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);
140 if (!throttled)
141 state_machine_.DidEnterBeginFrame();
142 ProcessScheduledActions();
143 if (!throttled)
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_)
151 return;
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);
158 TRACE_EVENT1(
159 "cc", "Scheduler::ProcessScheduledActions()", "action", action);
161 switch (action) {
162 case SchedulerStateMachine::ACTION_NONE:
163 break;
164 case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
165 client_->ScheduledActionSendBeginFrameToMainThread();
166 break;
167 case SchedulerStateMachine::ACTION_COMMIT:
168 client_->ScheduledActionCommit();
169 break;
170 case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS:
171 client_->ScheduledActionCheckForCompletedTileUploads();
172 break;
173 case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:
174 client_->ScheduledActionActivatePendingTreeIfNeeded();
175 break;
176 case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: {
177 ScheduledActionDrawAndSwapResult result =
178 client_->ScheduledActionDrawAndSwapIfPossible();
179 state_machine_.DidDrawIfPossibleCompleted(result.did_draw);
180 if (result.did_swap)
181 frame_rate_controller_->DidSwapBuffers();
182 break;
184 case SchedulerStateMachine::ACTION_DRAW_FORCED: {
185 ScheduledActionDrawAndSwapResult result =
186 client_->ScheduledActionDrawAndSwapForced();
187 if (result.did_swap)
188 frame_rate_controller_->DidSwapBuffers();
189 break;
191 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
192 client_->ScheduledActionBeginOutputSurfaceCreation();
193 break;
194 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
195 client_->ScheduledActionAcquireLayerTexturesForMainThread();
196 break;
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();
211 } // namespace cc