OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "cc/debug/traced_value.h" | 10 #include "cc/debug/traced_value.h" |
11 | 11 |
12 namespace cc { | 12 namespace cc { |
13 | 13 |
14 Scheduler::Scheduler(SchedulerClient* client, | 14 Scheduler::Scheduler(SchedulerClient* client, |
15 const SchedulerSettings& scheduler_settings) | 15 const SchedulerSettings& scheduler_settings) |
16 : settings_(scheduler_settings), | 16 : settings_(scheduler_settings), |
17 client_(client), | 17 client_(client), |
18 weak_factory_(this), | 18 weak_factory_(this), |
19 last_set_needs_begin_frame_(false), | 19 last_set_needs_begin_frame_(false), |
20 has_pending_begin_frame_(false), | |
21 state_machine_(scheduler_settings), | 20 state_machine_(scheduler_settings), |
22 inside_process_scheduled_actions_(false), | 21 inside_process_scheduled_actions_(false), |
23 inside_action_(SchedulerStateMachine::ACTION_NONE) { | 22 inside_action_(SchedulerStateMachine::ACTION_NONE) { |
24 DCHECK(client_); | 23 DCHECK(client_); |
25 DCHECK(!state_machine_.BeginFrameNeededToDrawByImplThread()); | 24 DCHECK(!state_machine_.BeginFrameNeededToDrawByImplThread()); |
26 } | 25 } |
27 | 26 |
28 Scheduler::~Scheduler() { | 27 Scheduler::~Scheduler() { |
29 client_->SetNeedsBeginFrameOnImplThread(false); | 28 client_->SetNeedsBeginFrameOnImplThread(false); |
30 } | 29 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 94 |
96 void Scheduler::DidLoseOutputSurface() { | 95 void Scheduler::DidLoseOutputSurface() { |
97 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 96 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
98 state_machine_.DidLoseOutputSurface(); | 97 state_machine_.DidLoseOutputSurface(); |
99 ProcessScheduledActions(); | 98 ProcessScheduledActions(); |
100 } | 99 } |
101 | 100 |
102 void Scheduler::DidCreateAndInitializeOutputSurface() { | 101 void Scheduler::DidCreateAndInitializeOutputSurface() { |
103 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 102 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
104 state_machine_.DidCreateAndInitializeOutputSurface(); | 103 state_machine_.DidCreateAndInitializeOutputSurface(); |
105 has_pending_begin_frame_ = false; | |
106 last_set_needs_begin_frame_ = false; | 104 last_set_needs_begin_frame_ = false; |
107 ProcessScheduledActions(); | 105 ProcessScheduledActions(); |
108 } | 106 } |
109 | 107 |
110 base::TimeTicks Scheduler::AnticipatedDrawTime() { | 108 base::TimeTicks Scheduler::AnticipatedDrawTime() { |
111 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); | 109 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); |
112 | 110 |
113 if (!last_set_needs_begin_frame_ || | 111 if (!last_set_needs_begin_frame_ || |
114 last_begin_frame_args_.interval <= base::TimeDelta()) | 112 last_begin_frame_args_.interval <= base::TimeDelta()) |
115 return base::TimeTicks(); | 113 return base::TimeTicks(); |
(...skipping 14 matching lines...) Expand all Loading... |
130 bool needs_begin_frame_to_draw = | 128 bool needs_begin_frame_to_draw = |
131 state_machine_.BeginFrameNeededToDrawByImplThread(); | 129 state_machine_.BeginFrameNeededToDrawByImplThread(); |
132 // We want to avoid proactive begin frames with the synchronous compositor | 130 // We want to avoid proactive begin frames with the synchronous compositor |
133 // because every SetNeedsBeginFrame will force a redraw. | 131 // because every SetNeedsBeginFrame will force a redraw. |
134 bool proactive_begin_frame_wanted = | 132 bool proactive_begin_frame_wanted = |
135 state_machine_.ProactiveBeginFrameWantedByImplThread() && | 133 state_machine_.ProactiveBeginFrameWantedByImplThread() && |
136 !settings_.using_synchronous_renderer_compositor && | 134 !settings_.using_synchronous_renderer_compositor && |
137 settings_.throttle_frame_production; | 135 settings_.throttle_frame_production; |
138 bool needs_begin_frame = needs_begin_frame_to_draw || | 136 bool needs_begin_frame = needs_begin_frame_to_draw || |
139 proactive_begin_frame_wanted; | 137 proactive_begin_frame_wanted; |
140 bool immediate_disables_needed = | |
141 settings_.using_synchronous_renderer_compositor; | |
142 | 138 |
143 // Determine if we need BeginFrame notifications. | 139 bool should_call_set_needs_begin_frame = |
144 // If we do, always request the BeginFrame immediately. | 140 // Always request the BeginFrame immediately if it wasn't needed before. |
145 // If not, only disable on the next BeginFrame to avoid unnecessary toggles. | 141 (needs_begin_frame && !last_set_needs_begin_frame_) || |
146 // The synchronous renderer compositor requires immediate disables though. | 142 // We always need to explicitly request our next BeginFrame. |
147 if ((needs_begin_frame || | 143 state_machine_.inside_begin_frame(); |
148 state_machine_.inside_begin_frame() || | 144 |
149 immediate_disables_needed) && | 145 if (should_call_set_needs_begin_frame) { |
150 (needs_begin_frame != last_set_needs_begin_frame_)) { | |
151 has_pending_begin_frame_ = false; | |
152 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); | 146 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); |
153 last_set_needs_begin_frame_ = needs_begin_frame; | 147 last_set_needs_begin_frame_ = needs_begin_frame; |
154 } | 148 } |
155 | 149 |
156 // Request another BeginFrame if we haven't drawn for now until we have | |
157 // deadlines implemented. | |
158 if (state_machine_.inside_begin_frame() && has_pending_begin_frame_) { | |
159 has_pending_begin_frame_ = false; | |
160 client_->SetNeedsBeginFrameOnImplThread(true); | |
161 } | |
162 | |
163 // Setup PollForAnticipatedDrawTriggers for cases where we want a proactive | 150 // Setup PollForAnticipatedDrawTriggers for cases where we want a proactive |
164 // BeginFrame but aren't requesting one. | 151 // BeginFrame but aren't requesting one. |
165 if (!needs_begin_frame && | 152 if (!needs_begin_frame && |
166 state_machine_.ProactiveBeginFrameWantedByImplThread()) { | 153 state_machine_.ProactiveBeginFrameWantedByImplThread()) { |
167 if (poll_for_draw_triggers_closure_.IsCancelled()) { | 154 if (poll_for_draw_triggers_closure_.IsCancelled()) { |
168 poll_for_draw_triggers_closure_.Reset( | 155 poll_for_draw_triggers_closure_.Reset( |
169 base::Bind(&Scheduler::PollForAnticipatedDrawTriggers, | 156 base::Bind(&Scheduler::PollForAnticipatedDrawTriggers, |
170 weak_factory_.GetWeakPtr())); | 157 weak_factory_.GetWeakPtr())); |
171 base::MessageLoop::current()->PostDelayedTask( | 158 base::MessageLoop::current()->PostDelayedTask( |
172 FROM_HERE, | 159 FROM_HERE, |
173 poll_for_draw_triggers_closure_.callback(), | 160 poll_for_draw_triggers_closure_.callback(), |
174 last_begin_frame_args_.interval); | 161 last_begin_frame_args_.interval); |
175 } | 162 } |
176 } else { | 163 } else { |
177 poll_for_draw_triggers_closure_.Cancel(); | 164 poll_for_draw_triggers_closure_.Cancel(); |
178 } | 165 } |
179 } | 166 } |
180 | 167 |
181 void Scheduler::BeginFrame(const BeginFrameArgs& args) { | 168 void Scheduler::BeginFrame(const BeginFrameArgs& args) { |
182 TRACE_EVENT0("cc", "Scheduler::BeginFrame"); | 169 TRACE_EVENT0("cc", "Scheduler::BeginFrame"); |
183 DCHECK(!has_pending_begin_frame_); | 170 DCHECK(!state_machine_.inside_begin_frame()); |
184 has_pending_begin_frame_ = true; | |
185 last_begin_frame_args_ = args; | 171 last_begin_frame_args_ = args; |
186 state_machine_.DidEnterBeginFrame(args); | 172 state_machine_.DidEnterBeginFrame(args); |
187 ProcessScheduledActions(); | 173 ProcessScheduledActions(); |
188 state_machine_.DidLeaveBeginFrame(); | 174 state_machine_.DidLeaveBeginFrame(); |
189 } | 175 } |
190 | 176 |
191 void Scheduler::PollForAnticipatedDrawTriggers() { | 177 void Scheduler::PollForAnticipatedDrawTriggers() { |
192 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); | 178 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); |
193 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); | 179 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); |
194 ProcessScheduledActions(); | 180 ProcessScheduledActions(); |
195 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); | 181 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); |
196 } | 182 } |
197 | 183 |
198 void Scheduler::DrawAndSwapIfPossible() { | 184 void Scheduler::DrawAndSwapIfPossible() { |
199 DrawSwapReadbackResult result = | 185 DrawSwapReadbackResult result = |
200 client_->ScheduledActionDrawAndSwapIfPossible(); | 186 client_->ScheduledActionDrawAndSwapIfPossible(); |
201 state_machine_.DidDrawIfPossibleCompleted(result.did_draw); | 187 state_machine_.DidDrawIfPossibleCompleted(result.did_draw); |
202 if (result.did_swap) | |
203 has_pending_begin_frame_ = false; | |
204 } | 188 } |
205 | 189 |
206 void Scheduler::DrawAndSwapForced() { | 190 void Scheduler::DrawAndSwapForced() { |
207 DrawSwapReadbackResult result = client_->ScheduledActionDrawAndSwapForced(); | 191 client_->ScheduledActionDrawAndSwapForced(); |
208 if (result.did_swap) | |
209 has_pending_begin_frame_ = false; | |
210 } | 192 } |
211 | 193 |
212 void Scheduler::DrawAndReadback() { | 194 void Scheduler::DrawAndReadback() { |
213 DrawSwapReadbackResult result = client_->ScheduledActionDrawAndReadback(); | 195 DrawSwapReadbackResult result = client_->ScheduledActionDrawAndReadback(); |
214 DCHECK(!result.did_swap); | 196 DCHECK(!result.did_swap); |
215 } | 197 } |
216 | 198 |
217 void Scheduler::ProcessScheduledActions() { | 199 void Scheduler::ProcessScheduledActions() { |
218 // We do not allow ProcessScheduledActions to be recursive. | 200 // We do not allow ProcessScheduledActions to be recursive. |
219 // The top-level call will iteratively execute the next action for us anyway. | 201 // The top-level call will iteratively execute the next action for us anyway. |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 257 |
276 SetupNextBeginFrameIfNeeded(); | 258 SetupNextBeginFrameIfNeeded(); |
277 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 259 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
278 } | 260 } |
279 | 261 |
280 bool Scheduler::WillDrawIfNeeded() const { | 262 bool Scheduler::WillDrawIfNeeded() const { |
281 return !state_machine_.PendingDrawsShouldBeAborted(); | 263 return !state_machine_.PendingDrawsShouldBeAborted(); |
282 } | 264 } |
283 | 265 |
284 } // namespace cc | 266 } // namespace cc |
OLD | NEW |