| 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 |