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 | |
5 #include "cc/scheduler/scheduler.h" | 4 #include "cc/scheduler/scheduler.h" |
6 | 5 |
7 #include <string> | 6 #include <string> |
8 #include <vector> | 7 #include <vector> |
9 | 8 |
10 #include "base/logging.h" | 9 #include "base/logging.h" |
11 #include "cc/test/scheduler_test_common.h" | 10 #include "cc/test/scheduler_test_common.h" |
12 #include "testing/gmock/include/gmock/gmock.h" | 11 #include "testing/gmock/include/gmock/gmock.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
14 | 13 |
15 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \ | 14 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \ |
16 EXPECT_EQ(expected_num_actions, client.num_actions_()); \ | 15 EXPECT_EQ(expected_num_actions, client.num_actions_()); \ |
17 ASSERT_LT(action_index, client.num_actions_()); \ | 16 ASSERT_LT(action_index, client.num_actions_()); \ |
18 do { \ | 17 do { \ |
19 EXPECT_STREQ(action, client.Action(action_index)); \ | 18 EXPECT_STREQ(action, client.Action(action_index)); \ |
20 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \ | 19 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \ |
21 ADD_FAILURE() << "Unexpected action: " << client.Action(i) << \ | 20 ADD_FAILURE() << "Unexpected action: " << client.Action(i) << \ |
22 " with state:\n" << client.StateForAction(action_index); \ | 21 " with state:\n" << client.StateForAction(action_index); \ |
23 } while (false) | 22 } while (false) |
24 | 23 |
25 #define EXPECT_SINGLE_ACTION(action, client) \ | 24 #define EXPECT_SINGLE_ACTION(action, client) \ |
26 EXPECT_ACTION(action, client, 0, 1) | 25 EXPECT_ACTION(action, client, 0, 1) |
27 | 26 |
28 namespace cc { | 27 namespace cc { |
29 namespace { | 28 namespace { |
30 | 29 |
| 30 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler) { |
| 31 scheduler->DidCreateAndInitializeOutputSurface(); |
| 32 scheduler->SetNeedsCommit(); |
| 33 scheduler->FinishCommit(); |
| 34 scheduler->SetHasTrees(0, 0); |
| 35 // Go through the motions to draw the commit. |
| 36 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 37 scheduler->OnBeginFrameDeadline(); |
| 38 // We need another BeginFrame so scheduler calls SetNeedsBeginFrame(false). |
| 39 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 40 scheduler->OnBeginFrameDeadline(); |
| 41 } |
| 42 |
31 class FakeSchedulerClient : public SchedulerClient { | 43 class FakeSchedulerClient : public SchedulerClient { |
32 public: | 44 public: |
33 FakeSchedulerClient() | 45 FakeSchedulerClient() |
34 : needs_begin_frame_(false) { | 46 : needs_begin_frame_(false) { |
35 Reset(); | 47 Reset(); |
36 } | 48 } |
37 | 49 |
38 void Reset() { | 50 void Reset() { |
39 actions_.clear(); | 51 actions_.clear(); |
40 states_.clear(); | 52 states_.clear(); |
(...skipping 30 matching lines...) Expand all Loading... |
71 // Scheduler Implementation. | 83 // Scheduler Implementation. |
72 virtual void SetNeedsBeginFrameOnImplThread(bool enable) OVERRIDE { | 84 virtual void SetNeedsBeginFrameOnImplThread(bool enable) OVERRIDE { |
73 actions_.push_back("SetNeedsBeginFrameOnImplThread"); | 85 actions_.push_back("SetNeedsBeginFrameOnImplThread"); |
74 states_.push_back(scheduler_->StateAsStringForTesting()); | 86 states_.push_back(scheduler_->StateAsStringForTesting()); |
75 needs_begin_frame_ = enable; | 87 needs_begin_frame_ = enable; |
76 } | 88 } |
77 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE { | 89 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE { |
78 actions_.push_back("ScheduledActionSendBeginFrameToMainThread"); | 90 actions_.push_back("ScheduledActionSendBeginFrameToMainThread"); |
79 states_.push_back(scheduler_->StateAsStringForTesting()); | 91 states_.push_back(scheduler_->StateAsStringForTesting()); |
80 } | 92 } |
81 virtual ScheduledActionDrawAndSwapResult | 93 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
82 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { | 94 OVERRIDE { |
83 actions_.push_back("ScheduledActionDrawAndSwapIfPossible"); | 95 actions_.push_back("ScheduledActionDrawAndSwapIfPossible"); |
84 states_.push_back(scheduler_->StateAsStringForTesting()); | 96 states_.push_back(scheduler_->StateAsStringForTesting()); |
85 num_draws_++; | 97 num_draws_++; |
86 return ScheduledActionDrawAndSwapResult(draw_will_happen_, | 98 return DrawSwapReadbackResult( |
87 draw_will_happen_ && | 99 draw_will_happen_, |
88 swap_will_happen_if_draw_happens_); | 100 draw_will_happen_ && swap_will_happen_if_draw_happens_, |
| 101 false); |
89 } | 102 } |
90 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() | 103 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
91 OVERRIDE { | |
92 actions_.push_back("ScheduledActionDrawAndSwapForced"); | 104 actions_.push_back("ScheduledActionDrawAndSwapForced"); |
93 states_.push_back(scheduler_->StateAsStringForTesting()); | 105 states_.push_back(scheduler_->StateAsStringForTesting()); |
94 return ScheduledActionDrawAndSwapResult(true, | 106 return DrawSwapReadbackResult( |
95 swap_will_happen_if_draw_happens_); | 107 true, swap_will_happen_if_draw_happens_, false); |
| 108 } |
| 109 virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() OVERRIDE { |
| 110 actions_.push_back("ScheduledActionDrawAndReadback"); |
| 111 states_.push_back(scheduler_->StateAsStringForTesting()); |
| 112 return DrawSwapReadbackResult(true, false, true); |
96 } | 113 } |
97 virtual void ScheduledActionCommit() OVERRIDE { | 114 virtual void ScheduledActionCommit() OVERRIDE { |
98 actions_.push_back("ScheduledActionCommit"); | 115 actions_.push_back("ScheduledActionCommit"); |
99 states_.push_back(scheduler_->StateAsStringForTesting()); | 116 states_.push_back(scheduler_->StateAsStringForTesting()); |
100 } | 117 } |
101 virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE { | 118 virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE { |
102 actions_.push_back("ScheduledActionUpdateVisibleTiles"); | 119 actions_.push_back("ScheduledActionUpdateVisibleTiles"); |
103 states_.push_back(scheduler_->StateAsStringForTesting()); | 120 states_.push_back(scheduler_->StateAsStringForTesting()); |
104 } | 121 } |
105 virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE { | 122 virtual void ScheduledActionActivatePendingTree() OVERRIDE { |
106 actions_.push_back("ScheduledActionActivatePendingTreeIfNeeded"); | 123 actions_.push_back("ScheduledActionActivatePendingTree"); |
107 states_.push_back(scheduler_->StateAsStringForTesting()); | 124 states_.push_back(scheduler_->StateAsStringForTesting()); |
108 } | 125 } |
109 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { | 126 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { |
110 actions_.push_back("ScheduledActionBeginOutputSurfaceCreation"); | 127 actions_.push_back("ScheduledActionBeginOutputSurfaceCreation"); |
111 states_.push_back(scheduler_->StateAsStringForTesting()); | 128 states_.push_back(scheduler_->StateAsStringForTesting()); |
112 } | 129 } |
113 virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { | 130 virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { |
114 actions_.push_back("ScheduledActionAcquireLayerTexturesForMainThread"); | 131 actions_.push_back("ScheduledActionAcquireLayerTexturesForMainThread"); |
115 states_.push_back(scheduler_->StateAsStringForTesting()); | 132 states_.push_back(scheduler_->StateAsStringForTesting()); |
116 } | 133 } |
117 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} | 134 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} |
118 virtual base::TimeDelta DrawDurationEstimate() OVERRIDE { | 135 virtual base::TimeDelta DrawDurationEstimate() OVERRIDE { |
119 return base::TimeDelta(); | 136 return base::TimeDelta(); |
120 } | 137 } |
121 virtual base::TimeDelta BeginFrameToCommitDurationEstimate() OVERRIDE { | 138 virtual base::TimeDelta BeginFrameToCommitDurationEstimate() OVERRIDE { |
122 return base::TimeDelta(); | 139 return base::TimeDelta(); |
123 } | 140 } |
124 virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE { | 141 virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE { |
125 return base::TimeDelta(); | 142 return base::TimeDelta(); |
126 } | 143 } |
127 | 144 |
| 145 virtual void PostBeginFrameDeadline(const base::Closure& closure, |
| 146 base::TimeTicks deadline) OVERRIDE { |
| 147 actions_.push_back("PostBeginFrameDeadlineTask"); |
| 148 states_.push_back(scheduler_->StateAsStringForTesting()); |
| 149 } |
| 150 |
| 151 virtual void DidBeginFrameDeadlineOnImplThread() OVERRIDE {} |
| 152 |
128 protected: | 153 protected: |
129 bool needs_begin_frame_; | 154 bool needs_begin_frame_; |
130 bool draw_will_happen_; | 155 bool draw_will_happen_; |
131 bool swap_will_happen_if_draw_happens_; | 156 bool swap_will_happen_if_draw_happens_; |
132 int num_draws_; | 157 int num_draws_; |
133 std::vector<const char*> actions_; | 158 std::vector<const char*> actions_; |
134 std::vector<std::string> states_; | 159 std::vector<std::string> states_; |
135 scoped_ptr<Scheduler> scheduler_; | 160 scoped_ptr<Scheduler> scheduler_; |
136 }; | 161 }; |
137 | 162 |
(...skipping 13 matching lines...) Expand all Loading... |
151 | 176 |
152 TEST(SchedulerTest, RequestCommit) { | 177 TEST(SchedulerTest, RequestCommit) { |
153 FakeSchedulerClient client; | 178 FakeSchedulerClient client; |
154 SchedulerSettings default_scheduler_settings; | 179 SchedulerSettings default_scheduler_settings; |
155 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 180 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
156 scheduler->SetCanStart(); | 181 scheduler->SetCanStart(); |
157 scheduler->SetVisible(true); | 182 scheduler->SetVisible(true); |
158 scheduler->SetCanDraw(true); | 183 scheduler->SetCanDraw(true); |
159 | 184 |
160 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); | 185 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
| 186 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 187 |
| 188 // SetNeedsCommit should begin the frame on the next BeginFrame. |
161 client.Reset(); | 189 client.Reset(); |
162 scheduler->DidCreateAndInitializeOutputSurface(); | 190 scheduler->SetNeedsCommit(); |
| 191 EXPECT_TRUE(client.needs_begin_frame()); |
| 192 client.Reset(); |
163 | 193 |
164 // SetNeedsCommit should begin the frame. | 194 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
165 scheduler->SetNeedsCommit(); | |
166 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); | 195 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
167 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 196 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
| 197 EXPECT_TRUE(client.needs_begin_frame()); |
| 198 client.Reset(); |
| 199 |
| 200 // If we don't swap on the deadline, we need to request another BeginFrame. |
| 201 scheduler->OnBeginFrameDeadline(); |
| 202 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
168 EXPECT_TRUE(client.needs_begin_frame()); | 203 EXPECT_TRUE(client.needs_begin_frame()); |
169 client.Reset(); | 204 client.Reset(); |
170 | 205 |
171 // FinishCommit should commit | 206 // FinishCommit should commit |
172 scheduler->FinishCommit(); | 207 scheduler->FinishCommit(); |
173 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); | 208 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); |
174 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | |
175 EXPECT_TRUE(client.needs_begin_frame()); | 209 EXPECT_TRUE(client.needs_begin_frame()); |
176 client.Reset(); | 210 client.Reset(); |
177 | 211 |
178 // BeginFrame should draw. | 212 // BeginFrame should prepare the draw. |
179 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 213 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
180 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); | 214 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
181 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 215 EXPECT_TRUE(client.needs_begin_frame()); |
| 216 client.Reset(); |
| 217 |
| 218 // BeginFrame deadline should draw. |
| 219 scheduler->OnBeginFrameDeadline(); |
| 220 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
| 221 client.Reset(); |
| 222 |
| 223 // The following BeginFrame deadline should SetNeedsBeginFrame(false) to avoid |
| 224 // excessive toggles. |
| 225 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 226 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
| 227 client.Reset(); |
| 228 |
| 229 scheduler->OnBeginFrameDeadline(); |
| 230 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
182 EXPECT_FALSE(client.needs_begin_frame()); | 231 EXPECT_FALSE(client.needs_begin_frame()); |
183 client.Reset(); | 232 client.Reset(); |
184 } | 233 } |
185 | 234 |
186 TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { | 235 TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { |
187 FakeSchedulerClient client; | 236 FakeSchedulerClient client; |
188 SchedulerSettings default_scheduler_settings; | 237 SchedulerSettings default_scheduler_settings; |
189 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 238 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
190 scheduler->SetCanStart(); | 239 scheduler->SetCanStart(); |
191 scheduler->SetVisible(true); | 240 scheduler->SetVisible(true); |
192 scheduler->SetCanDraw(true); | 241 scheduler->SetCanDraw(true); |
193 | 242 |
194 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); | 243 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
195 client.Reset(); | 244 InitializeOutputSurfaceAndFirstCommit(scheduler); |
196 scheduler->DidCreateAndInitializeOutputSurface(); | |
197 | |
198 // SetNedsCommit should begin the frame. | |
199 scheduler->SetNeedsCommit(); | |
200 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); | |
201 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | |
202 client.Reset(); | 245 client.Reset(); |
203 | 246 |
204 // Now SetNeedsCommit again. Calling here means we need a second frame. | 247 // SetNeddsCommit should begin the frame. |
205 scheduler->SetNeedsCommit(); | 248 scheduler->SetNeedsCommit(); |
206 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 1); | 249 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
| 250 client.Reset(); |
| 251 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 252 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
| 253 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
| 254 EXPECT_TRUE(client.needs_begin_frame()); |
207 client.Reset(); | 255 client.Reset(); |
208 | 256 |
209 // Since another commit is needed, FinishCommit should commit, | 257 // Now SetNeedsCommit again. Calling here means we need a second commit. |
210 // then begin another frame. | 258 scheduler->SetNeedsCommit(); |
| 259 EXPECT_EQ(client.num_actions_(), 0); |
| 260 client.Reset(); |
| 261 |
| 262 // Finish the first commit. |
211 scheduler->FinishCommit(); | 263 scheduler->FinishCommit(); |
212 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); | 264 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
213 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 265 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
| 266 client.Reset(); |
| 267 scheduler->OnBeginFrameDeadline(); |
| 268 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
214 client.Reset(); | 269 client.Reset(); |
215 | 270 |
216 // Tick should draw but then begin another frame. | 271 // Since another commit is needed, the next BeginFrame should initiate |
| 272 // the second commit. |
217 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 273 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
218 EXPECT_TRUE(client.needs_begin_frame()); | 274 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
219 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); | 275 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
220 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); | |
221 client.Reset(); | 276 client.Reset(); |
222 | 277 |
223 // Go back to quiescent state and verify we no longer request BeginFrames. | 278 // Finishing the commit before the deadline should post a new deadline task |
| 279 // to trigger the deadline early. |
224 scheduler->FinishCommit(); | 280 scheduler->FinishCommit(); |
| 281 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
| 282 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
| 283 client.Reset(); |
| 284 scheduler->OnBeginFrameDeadline(); |
| 285 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
| 286 EXPECT_TRUE(client.needs_begin_frame()); |
| 287 |
| 288 // On the next BeginFrame, go back to quiescent state and verify we no longer |
| 289 // request BeginFrames. |
225 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 290 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 291 scheduler->OnBeginFrameDeadline(); |
226 EXPECT_FALSE(client.needs_begin_frame()); | 292 EXPECT_FALSE(client.needs_begin_frame()); |
| 293 client.Reset(); |
227 } | 294 } |
228 | 295 |
229 TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { | 296 TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { |
230 FakeSchedulerClient client; | 297 FakeSchedulerClient client; |
231 SchedulerSettings default_scheduler_settings; | 298 SchedulerSettings default_scheduler_settings; |
232 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 299 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
233 scheduler->SetCanStart(); | 300 scheduler->SetCanStart(); |
234 scheduler->SetVisible(true); | 301 scheduler->SetVisible(true); |
235 scheduler->SetCanDraw(true); | 302 scheduler->SetCanDraw(true); |
236 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); | 303 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
237 | 304 |
| 305 InitializeOutputSurfaceAndFirstCommit(scheduler); |
238 client.Reset(); | 306 client.Reset(); |
239 scheduler->DidCreateAndInitializeOutputSurface(); | |
240 scheduler->SetNeedsRedraw(); | 307 scheduler->SetNeedsRedraw(); |
241 EXPECT_TRUE(scheduler->RedrawPending()); | 308 EXPECT_TRUE(scheduler->RedrawPending()); |
242 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); | 309 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
243 EXPECT_TRUE(client.needs_begin_frame()); | 310 EXPECT_TRUE(client.needs_begin_frame()); |
244 | 311 |
245 client.Reset(); | 312 client.Reset(); |
246 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 313 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
247 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); | 314 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
248 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 315 |
| 316 client.Reset(); |
| 317 scheduler->OnBeginFrameDeadline(); |
| 318 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
249 EXPECT_FALSE(scheduler->RedrawPending()); | 319 EXPECT_FALSE(scheduler->RedrawPending()); |
250 EXPECT_FALSE(client.needs_begin_frame()); | |
251 | 320 |
252 client.Reset(); | 321 client.Reset(); |
253 scheduler->SetMainThreadNeedsLayerTextures(); | 322 scheduler->SetMainThreadNeedsLayerTextures(); |
254 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", | 323 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
255 client); | 324 client); |
256 | 325 |
257 // We should request a BeginFrame in anticipation of a draw. | 326 // We should request a BeginFrame in anticipation of a draw. |
258 client.Reset(); | 327 client.Reset(); |
259 scheduler->SetNeedsRedraw(); | 328 scheduler->SetNeedsRedraw(); |
260 EXPECT_TRUE(scheduler->RedrawPending()); | 329 EXPECT_TRUE(scheduler->RedrawPending()); |
261 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); | 330 EXPECT_EQ(0, client.num_actions_()); |
262 EXPECT_TRUE(client.needs_begin_frame()); | |
263 | 331 |
264 // No draw happens since the textures are acquired by the main thread. | 332 // No draw happens since the textures are acquired by the main thread. |
265 client.Reset(); | 333 client.Reset(); |
266 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 334 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 335 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
| 336 |
| 337 client.Reset(); |
| 338 scheduler->OnBeginFrameDeadline(); |
267 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); | 339 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
268 EXPECT_TRUE(scheduler->RedrawPending()); | 340 EXPECT_TRUE(scheduler->RedrawPending()); |
269 EXPECT_TRUE(client.needs_begin_frame()); | 341 EXPECT_TRUE(client.needs_begin_frame()); |
270 | 342 |
| 343 client.Reset(); |
271 scheduler->SetNeedsCommit(); | 344 scheduler->SetNeedsCommit(); |
272 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2); | 345 EXPECT_EQ(0, client.num_actions_()); |
273 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); | 346 |
274 EXPECT_TRUE(client.needs_begin_frame()); | 347 client.Reset(); |
| 348 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 349 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
| 350 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
275 | 351 |
276 // Commit will release the texture. | 352 // Commit will release the texture. |
277 client.Reset(); | 353 client.Reset(); |
278 scheduler->FinishCommit(); | 354 scheduler->FinishCommit(); |
279 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); | 355 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); |
| 356 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
280 EXPECT_TRUE(scheduler->RedrawPending()); | 357 EXPECT_TRUE(scheduler->RedrawPending()); |
281 EXPECT_TRUE(client.needs_begin_frame()); | |
282 | 358 |
283 // Now we can draw again after the commit happens. | 359 // Now we can draw again after the commit happens. |
284 client.Reset(); | 360 client.Reset(); |
| 361 scheduler->OnBeginFrameDeadline(); |
| 362 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client); |
| 363 EXPECT_FALSE(scheduler->RedrawPending()); |
| 364 |
| 365 // SetNeedsBeginFrame(false) should be deferred to the end of the next |
| 366 // BeginFrame to avoid excessive toggling. |
| 367 EXPECT_TRUE(client.needs_begin_frame()); |
285 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 368 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
286 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); | 369 scheduler->OnBeginFrameDeadline(); |
287 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | |
288 EXPECT_FALSE(scheduler->RedrawPending()); | |
289 EXPECT_FALSE(client.needs_begin_frame()); | 370 EXPECT_FALSE(client.needs_begin_frame()); |
290 client.Reset(); | |
291 } | 371 } |
292 | 372 |
293 TEST(SchedulerTest, TextureAcquisitionCollision) { | 373 TEST(SchedulerTest, TextureAcquisitionCollision) { |
294 FakeSchedulerClient client; | 374 FakeSchedulerClient client; |
295 SchedulerSettings default_scheduler_settings; | 375 SchedulerSettings default_scheduler_settings; |
296 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 376 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
297 scheduler->SetCanStart(); | 377 scheduler->SetCanStart(); |
298 scheduler->SetVisible(true); | 378 scheduler->SetVisible(true); |
299 scheduler->SetCanDraw(true); | 379 scheduler->SetCanDraw(true); |
300 | 380 |
301 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); | 381 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
| 382 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 383 |
302 client.Reset(); | 384 client.Reset(); |
303 scheduler->DidCreateAndInitializeOutputSurface(); | |
304 | |
305 scheduler->SetNeedsCommit(); | 385 scheduler->SetNeedsCommit(); |
306 scheduler->SetMainThreadNeedsLayerTextures(); | 386 scheduler->SetMainThreadNeedsLayerTextures(); |
307 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 4); | 387 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2); |
308 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 4); | 388 EXPECT_ACTION( |
309 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", | 389 "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2); |
310 client, | 390 |
311 2, | |
312 4); | |
313 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 3, 4); | |
314 client.Reset(); | 391 client.Reset(); |
| 392 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 393 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
| 394 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
| 395 |
| 396 client.Reset(); |
| 397 scheduler->OnBeginFrameDeadline(); |
| 398 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); |
315 | 399 |
316 // Although the compositor cannot draw because textures are locked by main | 400 // Although the compositor cannot draw because textures are locked by main |
317 // thread, we continue requesting SetNeedsBeginFrame in anticipation of the | 401 // thread, we continue requesting SetNeedsBeginFrame in anticipation of the |
318 // unlock. | 402 // unlock. |
319 EXPECT_TRUE(client.needs_begin_frame()); | 403 EXPECT_TRUE(client.needs_begin_frame()); |
320 | 404 |
321 // Trigger the commit | 405 // Trigger the commit |
322 scheduler->FinishCommit(); | 406 scheduler->FinishCommit(); |
323 EXPECT_TRUE(client.needs_begin_frame()); | 407 EXPECT_TRUE(client.needs_begin_frame()); |
324 client.Reset(); | |
325 | 408 |
326 // Between commit and draw, texture acquisition for main thread delayed, | 409 // Between commit and draw, texture acquisition for main thread delayed, |
327 // and main thread blocks. | 410 // and main thread blocks. |
| 411 client.Reset(); |
328 scheduler->SetMainThreadNeedsLayerTextures(); | 412 scheduler->SetMainThreadNeedsLayerTextures(); |
329 EXPECT_EQ(0, client.num_actions_()); | 413 EXPECT_EQ(0, client.num_actions_()); |
330 client.Reset(); | |
331 | 414 |
332 // No implicit commit is expected. | 415 // No implicit commit is expected. |
| 416 client.Reset(); |
333 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 417 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
334 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); | 418 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client); |
335 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", | 419 |
336 client, | |
337 1, | |
338 3); | |
339 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3); | |
340 client.Reset(); | 420 client.Reset(); |
| 421 scheduler->OnBeginFrameDeadline(); |
| 422 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); |
| 423 EXPECT_ACTION( |
| 424 "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2); |
341 | 425 |
342 // Compositor not scheduled to draw because textures are locked by main | 426 // Although the compositor is not scheduled to draw because textures are |
343 // thread. | 427 // locked by main thread, we proactively request the begin frame. |
344 EXPECT_FALSE(client.needs_begin_frame()); | 428 EXPECT_TRUE(client.needs_begin_frame()); |
345 | 429 |
346 // Needs an explicit commit from the main thread. | 430 // Needs an explicit commit from the main thread. |
| 431 client.Reset(); |
347 scheduler->SetNeedsCommit(); | 432 scheduler->SetNeedsCommit(); |
| 433 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
348 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); | 434 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
349 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 435 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
350 client.Reset(); | 436 client.Reset(); |
351 | 437 |
352 // Trigger the commit | 438 // Trigger the commit |
353 scheduler->FinishCommit(); | 439 scheduler->FinishCommit(); |
354 EXPECT_TRUE(client.needs_begin_frame()); | 440 EXPECT_TRUE(client.needs_begin_frame()); |
355 } | 441 } |
356 | 442 |
357 TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { | 443 TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { |
358 FakeSchedulerClient client; | 444 FakeSchedulerClient client; |
359 SchedulerSettings default_scheduler_settings; | 445 SchedulerSettings default_scheduler_settings; |
360 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 446 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
361 scheduler->SetCanStart(); | 447 scheduler->SetCanStart(); |
362 scheduler->SetVisible(true); | 448 scheduler->SetVisible(true); |
363 scheduler->SetCanDraw(true); | 449 scheduler->SetCanDraw(true); |
364 | 450 |
365 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); | 451 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); |
366 client.Reset(); | 452 client.Reset(); |
367 scheduler->DidCreateAndInitializeOutputSurface(); | 453 scheduler->DidCreateAndInitializeOutputSurface(); |
368 | 454 |
369 scheduler->SetNeedsCommit(); | 455 scheduler->SetNeedsCommit(); |
| 456 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 457 scheduler->OnBeginFrameDeadline(); |
370 scheduler->FinishCommit(); | 458 scheduler->FinishCommit(); |
371 scheduler->SetMainThreadNeedsLayerTextures(); | 459 scheduler->SetMainThreadNeedsLayerTextures(); |
372 scheduler->SetNeedsCommit(); | 460 scheduler->SetNeedsCommit(); |
373 client.Reset(); | 461 client.Reset(); |
374 // Verify that pending texture acquisition fires when visibility | 462 // Verify that pending texture acquisition fires when visibility |
375 // is lost in order to avoid a deadlock. | 463 // is lost in order to avoid a deadlock. |
376 scheduler->SetVisible(false); | 464 scheduler->SetVisible(false); |
377 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", | 465 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", |
378 client); | 466 client); |
379 client.Reset(); | |
380 | 467 |
381 // Already sent a begin frame on this current frame, so wait. | 468 // Already sent a begin frame on this current frame, so wait. |
| 469 client.Reset(); |
382 scheduler->SetVisible(true); | 470 scheduler->SetVisible(true); |
383 EXPECT_EQ(0, client.num_actions_()); | 471 EXPECT_EQ(0, client.num_actions_()); |
384 client.Reset(); | 472 EXPECT_TRUE(client.needs_begin_frame()); |
385 | 473 |
386 // Regaining visibility with textures acquired by main thread while | 474 // Regaining visibility with textures acquired by main thread while |
387 // compositor is waiting for first draw should result in a request | 475 // compositor is waiting for first draw should result in a request |
388 // for a new frame in order to escape a deadlock. | 476 // for a new frame in order to escape a deadlock. |
| 477 client.Reset(); |
389 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 478 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
390 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); | 479 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); |
391 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); | 480 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2); |
392 } | 481 } |
393 | 482 |
394 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { | 483 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { |
395 public: | 484 public: |
396 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} | 485 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} |
397 virtual ScheduledActionDrawAndSwapResult | 486 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
398 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { | 487 OVERRIDE { |
399 // Only SetNeedsRedraw the first time this is called | 488 // Only SetNeedsRedraw the first time this is called |
400 if (!num_draws_) | 489 if (!num_draws_) |
401 scheduler_->SetNeedsRedraw(); | 490 scheduler_->SetNeedsRedraw(); |
402 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); | 491 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
403 } | 492 } |
404 | 493 |
405 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() | 494 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
406 OVERRIDE { | |
407 NOTREACHED(); | 495 NOTREACHED(); |
408 return ScheduledActionDrawAndSwapResult(true, true); | 496 return DrawSwapReadbackResult(true, true, false); |
409 } | 497 } |
410 | 498 |
411 virtual void ScheduledActionCommit() OVERRIDE {} | 499 virtual void ScheduledActionCommit() OVERRIDE {} |
412 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} | 500 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} |
413 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} | 501 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} |
414 }; | 502 }; |
415 | 503 |
416 // Tests for two different situations: | 504 // Tests for two different situations: |
417 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside | 505 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside |
418 // a ScheduledActionDrawAndSwap | 506 // a ScheduledActionDrawAndSwap |
419 // 2. the scheduler drawing twice inside a single tick | 507 // 2. the scheduler drawing twice inside a single tick |
420 TEST(SchedulerTest, RequestRedrawInsideDraw) { | 508 TEST(SchedulerTest, RequestRedrawInsideDraw) { |
421 SchedulerClientThatsetNeedsDrawInsideDraw client; | 509 SchedulerClientThatsetNeedsDrawInsideDraw client; |
422 SchedulerSettings default_scheduler_settings; | 510 SchedulerSettings default_scheduler_settings; |
423 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 511 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
424 scheduler->SetCanStart(); | 512 scheduler->SetCanStart(); |
425 scheduler->SetVisible(true); | 513 scheduler->SetVisible(true); |
426 scheduler->SetCanDraw(true); | 514 scheduler->SetCanDraw(true); |
427 scheduler->DidCreateAndInitializeOutputSurface(); | 515 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 516 client.Reset(); |
428 | 517 |
429 scheduler->SetNeedsRedraw(); | 518 scheduler->SetNeedsRedraw(); |
430 EXPECT_TRUE(scheduler->RedrawPending()); | 519 EXPECT_TRUE(scheduler->RedrawPending()); |
431 EXPECT_TRUE(client.needs_begin_frame()); | 520 EXPECT_TRUE(client.needs_begin_frame()); |
432 EXPECT_EQ(0, client.num_draws()); | 521 EXPECT_EQ(0, client.num_draws()); |
433 | 522 |
434 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 523 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 524 scheduler->OnBeginFrameDeadline(); |
435 EXPECT_EQ(1, client.num_draws()); | 525 EXPECT_EQ(1, client.num_draws()); |
436 EXPECT_TRUE(scheduler->RedrawPending()); | 526 EXPECT_TRUE(scheduler->RedrawPending()); |
437 EXPECT_TRUE(client.needs_begin_frame()); | 527 EXPECT_TRUE(client.needs_begin_frame()); |
438 | 528 |
439 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 529 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 530 scheduler->OnBeginFrameDeadline(); |
440 EXPECT_EQ(2, client.num_draws()); | 531 EXPECT_EQ(2, client.num_draws()); |
441 EXPECT_FALSE(scheduler->RedrawPending()); | 532 EXPECT_FALSE(scheduler->RedrawPending()); |
| 533 EXPECT_TRUE(client.needs_begin_frame()); |
| 534 |
| 535 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 536 scheduler->OnBeginFrameDeadline(); |
442 EXPECT_FALSE(client.needs_begin_frame()); | 537 EXPECT_FALSE(client.needs_begin_frame()); |
443 } | 538 } |
444 | 539 |
445 // Test that requesting redraw inside a failed draw doesn't lose the request. | 540 // Test that requesting redraw inside a failed draw doesn't lose the request. |
446 TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { | 541 TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { |
447 SchedulerClientThatsetNeedsDrawInsideDraw client; | 542 SchedulerClientThatsetNeedsDrawInsideDraw client; |
448 SchedulerSettings default_scheduler_settings; | 543 SchedulerSettings default_scheduler_settings; |
449 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 544 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
450 scheduler->SetCanStart(); | 545 scheduler->SetCanStart(); |
451 scheduler->SetVisible(true); | 546 scheduler->SetVisible(true); |
452 scheduler->SetCanDraw(true); | 547 scheduler->SetCanDraw(true); |
453 scheduler->DidCreateAndInitializeOutputSurface(); | 548 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 549 client.Reset(); |
454 | 550 |
455 client.SetDrawWillHappen(false); | 551 client.SetDrawWillHappen(false); |
456 | 552 |
457 scheduler->SetNeedsRedraw(); | 553 scheduler->SetNeedsRedraw(); |
458 EXPECT_TRUE(scheduler->RedrawPending()); | 554 EXPECT_TRUE(scheduler->RedrawPending()); |
459 EXPECT_TRUE(client.needs_begin_frame()); | 555 EXPECT_TRUE(client.needs_begin_frame()); |
460 EXPECT_EQ(0, client.num_draws()); | 556 EXPECT_EQ(0, client.num_draws()); |
461 | 557 |
462 // Fail the draw. | 558 // Fail the draw. |
463 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 559 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 560 scheduler->OnBeginFrameDeadline(); |
464 EXPECT_EQ(1, client.num_draws()); | 561 EXPECT_EQ(1, client.num_draws()); |
465 | 562 |
466 // We have a commit pending and the draw failed, and we didn't lose the redraw | 563 // We have a commit pending and the draw failed, and we didn't lose the redraw |
467 // request. | 564 // request. |
468 EXPECT_TRUE(scheduler->CommitPending()); | 565 EXPECT_TRUE(scheduler->CommitPending()); |
469 EXPECT_TRUE(scheduler->RedrawPending()); | 566 EXPECT_TRUE(scheduler->RedrawPending()); |
470 EXPECT_TRUE(client.needs_begin_frame()); | 567 EXPECT_TRUE(client.needs_begin_frame()); |
471 | 568 |
472 // Fail the draw again. | 569 // Fail the draw again. |
473 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 570 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 571 scheduler->OnBeginFrameDeadline(); |
474 EXPECT_EQ(2, client.num_draws()); | 572 EXPECT_EQ(2, client.num_draws()); |
475 EXPECT_TRUE(scheduler->CommitPending()); | 573 EXPECT_TRUE(scheduler->CommitPending()); |
476 EXPECT_TRUE(scheduler->RedrawPending()); | 574 EXPECT_TRUE(scheduler->RedrawPending()); |
477 EXPECT_TRUE(client.needs_begin_frame()); | 575 EXPECT_TRUE(client.needs_begin_frame()); |
478 | 576 |
479 // Draw successfully. | 577 // Draw successfully. |
480 client.SetDrawWillHappen(true); | 578 client.SetDrawWillHappen(true); |
481 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 579 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 580 scheduler->OnBeginFrameDeadline(); |
482 EXPECT_EQ(3, client.num_draws()); | 581 EXPECT_EQ(3, client.num_draws()); |
483 EXPECT_TRUE(scheduler->CommitPending()); | 582 EXPECT_TRUE(scheduler->CommitPending()); |
484 EXPECT_FALSE(scheduler->RedrawPending()); | 583 EXPECT_FALSE(scheduler->RedrawPending()); |
485 EXPECT_TRUE(client.needs_begin_frame()); | 584 EXPECT_TRUE(client.needs_begin_frame()); |
486 } | 585 } |
487 | 586 |
488 class SchedulerClientThatsetNeedsCommitInsideDraw : public FakeSchedulerClient { | 587 class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient { |
489 public: | 588 public: |
| 589 SchedulerClientThatSetNeedsCommitInsideDraw() |
| 590 : set_needs_commit_on_next_draw_(false) {} |
| 591 |
490 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} | 592 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} |
491 virtual ScheduledActionDrawAndSwapResult | 593 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() |
492 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { | 594 OVERRIDE { |
493 // Only SetNeedsCommit the first time this is called | 595 // Only SetNeedsCommit the first time this is called |
494 if (!num_draws_) | 596 if (set_needs_commit_on_next_draw_) { |
495 scheduler_->SetNeedsCommit(); | 597 scheduler_->SetNeedsCommit(); |
| 598 set_needs_commit_on_next_draw_ = false; |
| 599 } |
496 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); | 600 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); |
497 } | 601 } |
498 | 602 |
499 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() | 603 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE { |
500 OVERRIDE { | |
501 NOTREACHED(); | 604 NOTREACHED(); |
502 return ScheduledActionDrawAndSwapResult(true, true); | 605 return DrawSwapReadbackResult(true, true, false); |
503 } | 606 } |
504 | 607 |
505 virtual void ScheduledActionCommit() OVERRIDE {} | 608 virtual void ScheduledActionCommit() OVERRIDE {} |
506 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} | 609 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} |
507 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} | 610 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} |
| 611 |
| 612 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; } |
| 613 |
| 614 private: |
| 615 bool set_needs_commit_on_next_draw_; |
508 }; | 616 }; |
509 | 617 |
510 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that | 618 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that |
511 // happen inside a ScheduledActionDrawAndSwap | 619 // happen inside a ScheduledActionDrawAndSwap |
512 TEST(SchedulerTest, RequestCommitInsideDraw) { | 620 TEST(SchedulerTest, RequestCommitInsideDraw) { |
513 SchedulerClientThatsetNeedsCommitInsideDraw client; | 621 SchedulerClientThatSetNeedsCommitInsideDraw client; |
514 SchedulerSettings default_scheduler_settings; | 622 SchedulerSettings default_scheduler_settings; |
515 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 623 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
516 scheduler->SetCanStart(); | 624 scheduler->SetCanStart(); |
517 scheduler->SetVisible(true); | 625 scheduler->SetVisible(true); |
518 scheduler->SetCanDraw(true); | 626 scheduler->SetCanDraw(true); |
519 scheduler->DidCreateAndInitializeOutputSurface(); | 627 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 628 client.Reset(); |
520 | 629 |
| 630 EXPECT_FALSE(client.needs_begin_frame()); |
521 scheduler->SetNeedsRedraw(); | 631 scheduler->SetNeedsRedraw(); |
522 EXPECT_TRUE(scheduler->RedrawPending()); | 632 EXPECT_TRUE(scheduler->RedrawPending()); |
523 EXPECT_EQ(0, client.num_draws()); | 633 EXPECT_EQ(0, client.num_draws()); |
524 EXPECT_TRUE(client.needs_begin_frame()); | 634 EXPECT_TRUE(client.needs_begin_frame()); |
525 | 635 |
526 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 636 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 637 client.SetNeedsCommitOnNextDraw(); |
| 638 scheduler->OnBeginFrameDeadline(); |
527 EXPECT_EQ(1, client.num_draws()); | 639 EXPECT_EQ(1, client.num_draws()); |
528 EXPECT_TRUE(scheduler->CommitPending()); | 640 EXPECT_TRUE(scheduler->CommitPending()); |
529 EXPECT_TRUE(client.needs_begin_frame()); | 641 EXPECT_TRUE(client.needs_begin_frame()); |
530 scheduler->FinishCommit(); | 642 scheduler->FinishCommit(); |
531 | 643 |
532 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 644 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
533 EXPECT_EQ(2, client.num_draws());; | 645 scheduler->OnBeginFrameDeadline(); |
| 646 EXPECT_EQ(2, client.num_draws()); |
| 647 |
534 EXPECT_FALSE(scheduler->RedrawPending()); | 648 EXPECT_FALSE(scheduler->RedrawPending()); |
535 EXPECT_FALSE(scheduler->CommitPending()); | 649 EXPECT_FALSE(scheduler->CommitPending()); |
| 650 EXPECT_TRUE(client.needs_begin_frame()); |
| 651 |
| 652 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 653 scheduler->OnBeginFrameDeadline(); |
536 EXPECT_FALSE(client.needs_begin_frame()); | 654 EXPECT_FALSE(client.needs_begin_frame()); |
537 } | 655 } |
538 | 656 |
539 // Tests that when a draw fails then the pending commit should not be dropped. | 657 // Tests that when a draw fails then the pending commit should not be dropped. |
540 TEST(SchedulerTest, RequestCommitInsideFailedDraw) { | 658 TEST(SchedulerTest, RequestCommitInsideFailedDraw) { |
541 SchedulerClientThatsetNeedsDrawInsideDraw client; | 659 SchedulerClientThatsetNeedsDrawInsideDraw client; |
542 SchedulerSettings default_scheduler_settings; | 660 SchedulerSettings default_scheduler_settings; |
543 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 661 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
544 scheduler->SetCanStart(); | 662 scheduler->SetCanStart(); |
545 scheduler->SetVisible(true); | 663 scheduler->SetVisible(true); |
546 scheduler->SetCanDraw(true); | 664 scheduler->SetCanDraw(true); |
547 scheduler->DidCreateAndInitializeOutputSurface(); | 665 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 666 client.Reset(); |
548 | 667 |
549 client.SetDrawWillHappen(false); | 668 client.SetDrawWillHappen(false); |
550 | 669 |
551 scheduler->SetNeedsRedraw(); | 670 scheduler->SetNeedsRedraw(); |
552 EXPECT_TRUE(scheduler->RedrawPending()); | 671 EXPECT_TRUE(scheduler->RedrawPending()); |
553 EXPECT_TRUE(client.needs_begin_frame()); | 672 EXPECT_TRUE(client.needs_begin_frame()); |
554 EXPECT_EQ(0, client.num_draws()); | 673 EXPECT_EQ(0, client.num_draws()); |
555 | 674 |
556 // Fail the draw. | 675 // Fail the draw. |
557 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 676 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 677 scheduler->OnBeginFrameDeadline(); |
558 EXPECT_EQ(1, client.num_draws()); | 678 EXPECT_EQ(1, client.num_draws()); |
559 | 679 |
560 // We have a commit pending and the draw failed, and we didn't lose the commit | 680 // We have a commit pending and the draw failed, and we didn't lose the commit |
561 // request. | 681 // request. |
562 EXPECT_TRUE(scheduler->CommitPending()); | 682 EXPECT_TRUE(scheduler->CommitPending()); |
563 EXPECT_TRUE(scheduler->RedrawPending()); | 683 EXPECT_TRUE(scheduler->RedrawPending()); |
564 EXPECT_TRUE(client.needs_begin_frame()); | 684 EXPECT_TRUE(client.needs_begin_frame()); |
565 | 685 |
566 // Fail the draw again. | 686 // Fail the draw again. |
567 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 687 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 688 scheduler->OnBeginFrameDeadline(); |
568 EXPECT_EQ(2, client.num_draws()); | 689 EXPECT_EQ(2, client.num_draws()); |
569 EXPECT_TRUE(scheduler->CommitPending()); | 690 EXPECT_TRUE(scheduler->CommitPending()); |
570 EXPECT_TRUE(scheduler->RedrawPending()); | 691 EXPECT_TRUE(scheduler->RedrawPending()); |
571 EXPECT_TRUE(client.needs_begin_frame()); | 692 EXPECT_TRUE(client.needs_begin_frame()); |
572 | 693 |
573 // Draw successfully. | 694 // Draw successfully. |
574 client.SetDrawWillHappen(true); | 695 client.SetDrawWillHappen(true); |
575 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 696 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 697 scheduler->OnBeginFrameDeadline(); |
576 EXPECT_EQ(3, client.num_draws()); | 698 EXPECT_EQ(3, client.num_draws()); |
577 EXPECT_TRUE(scheduler->CommitPending()); | 699 EXPECT_TRUE(scheduler->CommitPending()); |
578 EXPECT_FALSE(scheduler->RedrawPending()); | 700 EXPECT_FALSE(scheduler->RedrawPending()); |
579 EXPECT_TRUE(client.needs_begin_frame()); | 701 EXPECT_TRUE(client.needs_begin_frame()); |
580 } | 702 } |
581 | 703 |
582 TEST(SchedulerTest, NoSwapWhenDrawFails) { | 704 TEST(SchedulerTest, NoSwapWhenDrawFails) { |
583 SchedulerClientThatsetNeedsCommitInsideDraw client; | 705 SchedulerClientThatSetNeedsCommitInsideDraw client; |
584 SchedulerSettings default_scheduler_settings; | 706 SchedulerSettings default_scheduler_settings; |
585 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 707 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
586 scheduler->SetCanStart(); | 708 scheduler->SetCanStart(); |
587 scheduler->SetVisible(true); | 709 scheduler->SetVisible(true); |
588 scheduler->SetCanDraw(true); | 710 scheduler->SetCanDraw(true); |
589 scheduler->DidCreateAndInitializeOutputSurface(); | 711 InitializeOutputSurfaceAndFirstCommit(scheduler); |
| 712 client.Reset(); |
590 | 713 |
591 scheduler->SetNeedsRedraw(); | 714 scheduler->SetNeedsRedraw(); |
592 EXPECT_TRUE(scheduler->RedrawPending()); | 715 EXPECT_TRUE(scheduler->RedrawPending()); |
593 EXPECT_TRUE(client.needs_begin_frame()); | 716 EXPECT_TRUE(client.needs_begin_frame()); |
594 EXPECT_EQ(0, client.num_draws()); | 717 EXPECT_EQ(0, client.num_draws()); |
595 | 718 |
596 // Draw successfully, this starts a new frame. | 719 // Draw successfully, this starts a new frame. |
597 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 720 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 721 scheduler->OnBeginFrameDeadline(); |
598 EXPECT_EQ(1, client.num_draws()); | 722 EXPECT_EQ(1, client.num_draws()); |
599 | 723 |
600 scheduler->SetNeedsRedraw(); | 724 scheduler->SetNeedsRedraw(); |
601 EXPECT_TRUE(scheduler->RedrawPending()); | 725 EXPECT_TRUE(scheduler->RedrawPending()); |
602 EXPECT_TRUE(client.needs_begin_frame()); | 726 EXPECT_TRUE(client.needs_begin_frame()); |
603 | 727 |
604 // Fail to draw, this should not start a frame. | 728 // Fail to draw, this should not start a frame. |
605 client.SetDrawWillHappen(false); | 729 client.SetDrawWillHappen(false); |
606 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); | 730 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); |
| 731 scheduler->OnBeginFrameDeadline(); |
607 EXPECT_EQ(2, client.num_draws()); | 732 EXPECT_EQ(2, client.num_draws()); |
608 } | 733 } |
609 | 734 |
610 TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) { | 735 TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) { |
611 FakeSchedulerClient client; | 736 FakeSchedulerClient client; |
612 SchedulerSettings default_scheduler_settings; | 737 SchedulerSettings default_scheduler_settings; |
613 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); | 738 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
614 | 739 |
615 // Tell the client that it will fail to swap. | 740 // Tell the client that it will fail to swap. |
616 client.SetDrawWillHappen(true); | 741 client.SetDrawWillHappen(true); |
617 client.SetSwapWillHappenIfDrawHappens(false); | 742 client.SetSwapWillHappenIfDrawHappens(false); |
618 | 743 |
619 // Get the compositor to do a ScheduledActionDrawAndSwapForced. | 744 // Get the compositor to do a ScheduledActionDrawAndReadback. |
620 scheduler->SetCanDraw(true); | 745 scheduler->SetCanDraw(true); |
621 scheduler->SetNeedsRedraw(); | 746 scheduler->SetNeedsRedraw(); |
622 scheduler->SetNeedsForcedRedraw(); | 747 scheduler->SetNeedsForcedCommitForReadback(); |
623 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapForced")); | 748 scheduler->FinishCommit(); |
| 749 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
| 750 } |
| 751 |
| 752 TEST(SchedulerTest, BackToBackReadbackAllowed) { |
| 753 // Some clients call readbacks twice in a row before the replacement |
| 754 // commit comes in. Make sure it is allowed. |
| 755 FakeSchedulerClient client; |
| 756 SchedulerSettings default_scheduler_settings; |
| 757 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); |
| 758 |
| 759 // Get the compositor to do 2 ScheduledActionDrawAndReadbacks before |
| 760 // the replacement commit comes in. |
| 761 scheduler->SetCanDraw(true); |
| 762 scheduler->SetNeedsRedraw(); |
| 763 scheduler->SetNeedsForcedCommitForReadback(); |
| 764 scheduler->FinishCommit(); |
| 765 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
| 766 |
| 767 client.Reset(); |
| 768 scheduler->SetNeedsForcedCommitForReadback(); |
| 769 scheduler->FinishCommit(); |
| 770 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback")); |
| 771 |
| 772 // The replacement commit comes in after 2 readbacks. |
| 773 client.Reset(); |
| 774 scheduler->FinishCommit(); |
624 } | 775 } |
625 | 776 |
626 } // namespace | 777 } // namespace |
627 } // namespace cc | 778 } // namespace cc |
OLD | NEW |