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