OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 PushAction("SendBeginMainFrameNotExpectedSoon"); | 175 PushAction("SendBeginMainFrameNotExpectedSoon"); |
176 } | 176 } |
177 | 177 |
178 bool IsInsideBeginImplFrame() const { return inside_begin_impl_frame_; } | 178 bool IsInsideBeginImplFrame() const { return inside_begin_impl_frame_; } |
179 | 179 |
180 base::Callback<bool(void)> InsideBeginImplFrame(bool state) { | 180 base::Callback<bool(void)> InsideBeginImplFrame(bool state) { |
181 return base::Bind(&FakeSchedulerClient::InsideBeginImplFrameCallback, | 181 return base::Bind(&FakeSchedulerClient::InsideBeginImplFrameCallback, |
182 base::Unretained(this), state); | 182 base::Unretained(this), state); |
183 } | 183 } |
184 | 184 |
185 bool IsCurrentFrame(int last_frame_number) const { | |
186 return scheduler_->current_frame_number() == last_frame_number; | |
187 } | |
188 | |
189 base::Callback<bool(void)> FrameHasNotAdvancedCallback() { | |
190 return base::Bind(&FakeSchedulerClient::IsCurrentFrame, | |
191 base::Unretained(this), | |
192 scheduler_->current_frame_number()); | |
193 } | |
194 | |
195 void PushAction(const char* description) { | 185 void PushAction(const char* description) { |
196 actions_.push_back(description); | 186 actions_.push_back(description); |
197 states_.push_back(scheduler_->AsValue()); | 187 states_.push_back(scheduler_->AsValue()); |
198 } | 188 } |
199 | 189 |
200 // FakeExternalBeginFrameSource::Client implementation. | 190 // FakeExternalBeginFrameSource::Client implementation. |
201 void OnAddObserver(BeginFrameObserver* obs) override { | 191 void OnAddObserver(BeginFrameObserver* obs) override { |
202 PushAction("AddObserver(this)"); | 192 PushAction("AddObserver(this)"); |
203 } | 193 } |
204 void OnRemoveObserver(BeginFrameObserver* obs) override { | 194 void OnRemoveObserver(BeginFrameObserver* obs) override { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 360 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
371 client_->Reset(); | 361 client_->Reset(); |
372 } | 362 } |
373 | 363 |
374 // As this function contains EXPECT macros, to allow debugging it should be | 364 // As this function contains EXPECT macros, to allow debugging it should be |
375 // called inside EXPECT_SCOPED like so; | 365 // called inside EXPECT_SCOPED like so; |
376 // EXPECT_SCOPED(client.AdvanceFrame()); | 366 // EXPECT_SCOPED(client.AdvanceFrame()); |
377 void AdvanceFrame() { | 367 void AdvanceFrame() { |
378 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), | 368 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), |
379 "FakeSchedulerClient::AdvanceFrame"); | 369 "FakeSchedulerClient::AdvanceFrame"); |
| 370 // Consume any previous deadline first, if no deadline is currently |
| 371 // pending, InsideBeginImplFrame will return false straight away and we |
| 372 // will run no tasks. |
| 373 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 374 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
380 | 375 |
381 // Send the next BeginFrame message if using an external source, otherwise | 376 // Send the next BeginFrame message if using an external source, otherwise |
382 // it will be already in the task queue. | 377 // it will be already in the task queue. |
383 if (scheduler_->begin_frame_source() == | 378 if (scheduler_->begin_frame_source() == |
384 fake_external_begin_frame_source_.get()) { | 379 fake_external_begin_frame_source_.get()) { |
385 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 380 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
386 SendNextBeginFrame(); | 381 SendNextBeginFrame(); |
387 } else { | 382 } |
388 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); | 383 |
| 384 if (!scheduler_->settings().using_synchronous_renderer_compositor) { |
| 385 // Then run tasks until new deadline is scheduled. |
| 386 EXPECT_TRUE( |
| 387 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 388 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
389 } | 389 } |
390 } | 390 } |
391 | 391 |
392 BeginFrameArgs SendNextBeginFrame() { | 392 BeginFrameArgs SendNextBeginFrame() { |
393 DCHECK_EQ(scheduler_->begin_frame_source(), | 393 DCHECK_EQ(scheduler_->begin_frame_source(), |
394 fake_external_begin_frame_source_.get()); | 394 fake_external_begin_frame_source_.get()); |
395 // Creep the time forward so that any BeginFrameArgs is not equal to the | 395 // Creep the time forward so that any BeginFrameArgs is not equal to the |
396 // last one otherwise we violate the BeginFrameSource contract. | 396 // last one otherwise we violate the BeginFrameSource contract. |
397 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | 397 now_src_->Advance(BeginFrameArgs::DefaultInterval()); |
398 BeginFrameArgs args = | 398 BeginFrameArgs args = |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2031 EXPECT_NO_ACTION(client_); | 2031 EXPECT_NO_ACTION(client_); |
2032 | 2032 |
2033 // Activate the pending tree, which also unblocks the commit immediately | 2033 // Activate the pending tree, which also unblocks the commit immediately |
2034 // while we are in an idle state. | 2034 // while we are in an idle state. |
2035 client_->Reset(); | 2035 client_->Reset(); |
2036 scheduler_->NotifyReadyToActivate(); | 2036 scheduler_->NotifyReadyToActivate(); |
2037 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); | 2037 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); |
2038 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); | 2038 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); |
2039 } | 2039 } |
2040 | 2040 |
| 2041 TEST_F(SchedulerTest, BeginRetroFrame) { |
| 2042 scheduler_settings_.use_external_begin_frame_source = true; |
| 2043 SetUpScheduler(true); |
| 2044 |
| 2045 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2046 scheduler_->SetNeedsBeginMainFrame(); |
| 2047 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2048 client_->Reset(); |
| 2049 |
| 2050 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2051 // This is the first BeginFrame, which will be handled immediately. |
| 2052 BeginFrameArgs args = |
| 2053 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2054 args.deadline += base::TimeDelta::FromHours(1); |
| 2055 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2056 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2057 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2058 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2059 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2060 client_->Reset(); |
| 2061 |
| 2062 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2063 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2064 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2065 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2066 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2067 |
| 2068 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2069 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2070 EXPECT_NO_ACTION(client_); |
| 2071 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2072 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2073 client_->Reset(); |
| 2074 |
| 2075 // NotifyReadyToCommit should trigger the commit. |
| 2076 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2077 scheduler_->NotifyReadyToCommit(); |
| 2078 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2079 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2080 client_->Reset(); |
| 2081 |
| 2082 // NotifyReadyToActivate should trigger the activation. |
| 2083 scheduler_->NotifyReadyToActivate(); |
| 2084 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2085 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2086 client_->Reset(); |
| 2087 |
| 2088 // BeginImplFrame should prepare the draw. |
| 2089 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2090 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2091 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2092 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2093 client_->Reset(); |
| 2094 |
| 2095 // BeginImplFrame deadline should draw. |
| 2096 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2097 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2098 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2099 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2100 client_->Reset(); |
| 2101 |
| 2102 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) |
| 2103 // to avoid excessive toggles. |
| 2104 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2105 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
| 2106 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2107 client_->Reset(); |
| 2108 |
| 2109 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2110 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); |
| 2111 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); |
| 2112 client_->Reset(); |
| 2113 } |
| 2114 |
| 2115 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { |
| 2116 scheduler_settings_.use_external_begin_frame_source = true; |
| 2117 SetUpScheduler(true); |
| 2118 |
| 2119 scheduler_->SetNeedsBeginMainFrame(); |
| 2120 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2121 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2122 |
| 2123 client_->Reset(); |
| 2124 EXPECT_SCOPED(AdvanceFrame()); |
| 2125 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2126 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2127 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2128 |
| 2129 client_->Reset(); |
| 2130 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2131 |
| 2132 client_->Reset(); |
| 2133 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
| 2134 // This BeginFrame is queued up as a retro frame. |
| 2135 EXPECT_NO_ACTION(client_); |
| 2136 // The previous deadline is still pending. |
| 2137 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2138 |
| 2139 client_->Reset(); |
| 2140 // This main frame activating should schedule the (previous) deadline to |
| 2141 // trigger immediately. |
| 2142 scheduler_->NotifyReadyToCommit(); |
| 2143 scheduler_->NotifyReadyToActivate(); |
| 2144 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); |
| 2145 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); |
| 2146 |
| 2147 client_->Reset(); |
| 2148 // The deadline task should trigger causing a draw. |
| 2149 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2150 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2151 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2152 |
| 2153 // Keep animating. |
| 2154 client_->Reset(); |
| 2155 scheduler_->SetNeedsOneBeginImplFrame(); |
| 2156 scheduler_->SetNeedsRedraw(); |
| 2157 EXPECT_NO_ACTION(client_); |
| 2158 |
| 2159 // Let's advance to the retro frame's deadline. |
| 2160 now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks()); |
| 2161 |
| 2162 // The retro frame hasn't expired yet. |
| 2163 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false)); |
| 2164 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2165 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2166 |
| 2167 // This is an immediate deadline case. |
| 2168 client_->Reset(); |
| 2169 task_runner().RunPendingTasks(); |
| 2170 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2171 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
| 2172 } |
| 2173 |
| 2174 TEST_F(SchedulerTest, RetroFrameExpiresOnTime) { |
| 2175 scheduler_settings_.use_external_begin_frame_source = true; |
| 2176 SetUpScheduler(true); |
| 2177 |
| 2178 scheduler_->SetNeedsBeginMainFrame(); |
| 2179 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2180 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2181 |
| 2182 client_->Reset(); |
| 2183 EXPECT_SCOPED(AdvanceFrame()); |
| 2184 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2185 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2186 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2187 |
| 2188 client_->Reset(); |
| 2189 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2190 |
| 2191 client_->Reset(); |
| 2192 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
| 2193 // This BeginFrame is queued up as a retro frame. |
| 2194 EXPECT_NO_ACTION(client_); |
| 2195 // The previous deadline is still pending. |
| 2196 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2197 |
| 2198 client_->Reset(); |
| 2199 // This main frame activating should schedule the (previous) deadline to |
| 2200 // trigger immediately. |
| 2201 scheduler_->NotifyReadyToCommit(); |
| 2202 scheduler_->NotifyReadyToActivate(); |
| 2203 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); |
| 2204 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); |
| 2205 |
| 2206 client_->Reset(); |
| 2207 // The deadline task should trigger causing a draw. |
| 2208 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2209 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2210 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2211 |
| 2212 // Keep animating. |
| 2213 client_->Reset(); |
| 2214 scheduler_->SetNeedsOneBeginImplFrame(); |
| 2215 scheduler_->SetNeedsRedraw(); |
| 2216 EXPECT_NO_ACTION(client_); |
| 2217 |
| 2218 // Let's advance sufficiently past the retro frame's deadline. |
| 2219 now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks() + |
| 2220 base::TimeDelta::FromMicroseconds(1)); |
| 2221 |
| 2222 // The retro frame should've expired. |
| 2223 EXPECT_NO_ACTION(client_); |
| 2224 } |
| 2225 |
| 2226 TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) { |
| 2227 scheduler_settings_.use_external_begin_frame_source = true; |
| 2228 SetUpScheduler(true); |
| 2229 |
| 2230 scheduler_->SetNeedsBeginMainFrame(); |
| 2231 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2232 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2233 |
| 2234 BeginFrameArgs missed_frame_args = |
| 2235 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2236 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 2237 |
| 2238 // Advance to the deadline. |
| 2239 now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks()); |
| 2240 |
| 2241 // Missed frame is handled because it's on time. |
| 2242 client_->Reset(); |
| 2243 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 2244 EXPECT_TRUE( |
| 2245 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 2246 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2247 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2248 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2249 } |
| 2250 |
| 2251 TEST_F(SchedulerTest, MissedFrameExpiresOnTime) { |
| 2252 scheduler_settings_.use_external_begin_frame_source = true; |
| 2253 SetUpScheduler(true); |
| 2254 |
| 2255 scheduler_->SetNeedsBeginMainFrame(); |
| 2256 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2257 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2258 |
| 2259 BeginFrameArgs missed_frame_args = |
| 2260 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2261 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 2262 |
| 2263 // Advance sufficiently past the deadline. |
| 2264 now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks() + |
| 2265 base::TimeDelta::FromMicroseconds(1)); |
| 2266 |
| 2267 // Missed frame is dropped because it's too late. |
| 2268 client_->Reset(); |
| 2269 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 2270 EXPECT_FALSE( |
| 2271 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 2272 EXPECT_NO_ACTION(client_); |
| 2273 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2274 } |
| 2275 |
2041 void SchedulerTest::BeginFramesNotFromClient( | 2276 void SchedulerTest::BeginFramesNotFromClient( |
2042 bool use_external_begin_frame_source, | 2277 bool use_external_begin_frame_source, |
2043 bool throttle_frame_production) { | 2278 bool throttle_frame_production) { |
2044 scheduler_settings_.use_external_begin_frame_source = | 2279 scheduler_settings_.use_external_begin_frame_source = |
2045 use_external_begin_frame_source; | 2280 use_external_begin_frame_source; |
2046 scheduler_settings_.throttle_frame_production = throttle_frame_production; | 2281 scheduler_settings_.throttle_frame_production = throttle_frame_production; |
2047 SetUpScheduler(true); | 2282 SetUpScheduler(true); |
2048 | 2283 |
2049 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame | 2284 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame |
2050 // without calling SetNeedsBeginFrame. | 2285 // without calling SetNeedsBeginFrame. |
2051 scheduler_->SetNeedsBeginMainFrame(); | 2286 scheduler_->SetNeedsBeginMainFrame(); |
2052 EXPECT_NO_ACTION(client_); | 2287 EXPECT_NO_ACTION(client_); |
2053 client_->Reset(); | 2288 client_->Reset(); |
2054 | 2289 |
2055 EXPECT_SCOPED(AdvanceFrame()); | 2290 // When the client-driven BeginFrame are disabled, the scheduler posts it's |
| 2291 // own BeginFrame tasks. |
| 2292 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
2056 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 2293 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
2057 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 2294 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
2058 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | 2295 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2059 client_->Reset(); | 2296 client_->Reset(); |
2060 | 2297 |
2061 // Can't run the deadline task because it can race with begin frame for the | 2298 // If we don't swap on the deadline, we wait for the next BeginFrame. |
2062 // SyntheticBFS case. | 2299 task_runner().RunPendingTasks(); // Run posted deadline. |
2063 EXPECT_SCOPED(AdvanceFrame()); | 2300 EXPECT_NO_ACTION(client_); |
2064 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | 2301 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
2065 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | |
2066 client_->Reset(); | 2302 client_->Reset(); |
2067 | 2303 |
2068 // NotifyReadyToCommit should trigger the commit. | 2304 // NotifyReadyToCommit should trigger the commit. |
2069 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); | 2305 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
2070 scheduler_->NotifyReadyToCommit(); | 2306 scheduler_->NotifyReadyToCommit(); |
2071 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 2307 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
2072 client_->Reset(); | 2308 client_->Reset(); |
2073 | 2309 |
2074 // NotifyReadyToActivate should trigger the activation. | 2310 // NotifyReadyToActivate should trigger the activation. |
2075 scheduler_->NotifyReadyToActivate(); | 2311 scheduler_->NotifyReadyToActivate(); |
2076 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); | 2312 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
2077 client_->Reset(); | 2313 client_->Reset(); |
2078 | 2314 |
2079 // BeginImplFrame deadline should draw. The following BeginImplFrame deadline | 2315 // BeginImplFrame should prepare the draw. |
2080 // should SetNeedsBeginFrame(false) to avoid excessive toggles. | 2316 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
2081 EXPECT_SCOPED(AdvanceFrame()); | 2317 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
2082 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); | 2318 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2083 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); | 2319 client_->Reset(); |
| 2320 |
| 2321 // BeginImplFrame deadline should draw. |
| 2322 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2323 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2324 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2325 client_->Reset(); |
| 2326 |
| 2327 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) |
| 2328 // to avoid excessive toggles. |
| 2329 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
| 2330 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
| 2331 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2084 client_->Reset(); | 2332 client_->Reset(); |
2085 | 2333 |
2086 // Make sure SetNeedsBeginFrame isn't called on the client | 2334 // Make sure SetNeedsBeginFrame isn't called on the client |
2087 // when the BeginFrame is no longer needed. | 2335 // when the BeginFrame is no longer needed. |
2088 task_runner().RunPendingTasks(); // Run posted deadline. | 2336 task_runner().RunPendingTasks(); // Run posted deadline. |
2089 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); | 2337 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); |
2090 client_->Reset(); | 2338 client_->Reset(); |
2091 } | 2339 } |
2092 | 2340 |
2093 TEST_F(SchedulerTest, SyntheticBeginFrames) { | 2341 TEST_F(SchedulerTest, SyntheticBeginFrames) { |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2372 EXPECT_NO_ACTION(client_); | 2620 EXPECT_NO_ACTION(client_); |
2373 | 2621 |
2374 client_->Reset(); | 2622 client_->Reset(); |
2375 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); | 2623 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
2376 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); | 2624 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); |
2377 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4); | 2625 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4); |
2378 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); | 2626 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); |
2379 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); | 2627 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); |
2380 } | 2628 } |
2381 | 2629 |
| 2630 TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) { |
| 2631 scheduler_settings_.use_external_begin_frame_source = true; |
| 2632 SetUpScheduler(true); |
| 2633 |
| 2634 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2635 scheduler_->SetNeedsBeginMainFrame(); |
| 2636 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2637 |
| 2638 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2639 // This is the first BeginFrame, which will be handled immediately. |
| 2640 client_->Reset(); |
| 2641 BeginFrameArgs args = |
| 2642 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2643 args.deadline += base::TimeDelta::FromHours(1); |
| 2644 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2645 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2646 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2647 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2648 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2649 |
| 2650 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2651 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2652 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2653 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2654 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2655 |
| 2656 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2657 client_->Reset(); |
| 2658 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2659 EXPECT_NO_ACTION(client_); |
| 2660 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2661 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2662 |
| 2663 // NotifyReadyToCommit should trigger the commit. |
| 2664 client_->Reset(); |
| 2665 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2666 scheduler_->NotifyReadyToCommit(); |
| 2667 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2668 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2669 |
| 2670 // NotifyReadyToActivate should trigger the activation. |
| 2671 client_->Reset(); |
| 2672 scheduler_->NotifyReadyToActivate(); |
| 2673 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2674 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2675 |
| 2676 client_->Reset(); |
| 2677 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2678 scheduler_->DidLoseOutputSurface(); |
| 2679 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); |
| 2680 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); |
| 2681 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
| 2682 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2683 |
| 2684 // Posted BeginRetroFrame is aborted. |
| 2685 client_->Reset(); |
| 2686 task_runner().RunPendingTasks(); |
| 2687 EXPECT_NO_ACTION(client_); |
| 2688 } |
| 2689 |
| 2690 TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) { |
| 2691 scheduler_settings_.use_external_begin_frame_source = true; |
| 2692 SetUpScheduler(true); |
| 2693 |
| 2694 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2695 scheduler_->SetNeedsBeginMainFrame(); |
| 2696 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2697 |
| 2698 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2699 // This is the first BeginFrame, which will be handled immediately. |
| 2700 client_->Reset(); |
| 2701 BeginFrameArgs args = |
| 2702 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2703 args.deadline += base::TimeDelta::FromHours(1); |
| 2704 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2705 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2706 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2707 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2708 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2709 |
| 2710 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2711 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2712 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2713 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2714 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2715 |
| 2716 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2717 client_->Reset(); |
| 2718 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2719 EXPECT_NO_ACTION(client_); |
| 2720 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2721 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2722 |
| 2723 // NotifyReadyToCommit should trigger the commit. |
| 2724 client_->Reset(); |
| 2725 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2726 scheduler_->NotifyReadyToCommit(); |
| 2727 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2728 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2729 |
| 2730 // NotifyReadyToActivate should trigger the activation. |
| 2731 client_->Reset(); |
| 2732 scheduler_->NotifyReadyToActivate(); |
| 2733 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2734 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2735 |
| 2736 // BeginImplFrame should prepare the draw. |
| 2737 client_->Reset(); |
| 2738 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2739 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2740 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2741 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2742 |
| 2743 client_->Reset(); |
| 2744 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2745 scheduler_->DidLoseOutputSurface(); |
| 2746 EXPECT_NO_ACTION(client_); |
| 2747 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2748 |
| 2749 // BeginImplFrame deadline should abort drawing. |
| 2750 client_->Reset(); |
| 2751 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2752 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3); |
| 2753 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); |
| 2754 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
| 2755 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2756 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
| 2757 |
| 2758 // No more BeginRetroFrame because BeginRetroFrame queue is cleared. |
| 2759 client_->Reset(); |
| 2760 task_runner().RunPendingTasks(); |
| 2761 EXPECT_NO_ACTION(client_); |
| 2762 } |
| 2763 |
2382 TEST_F(SchedulerTest, DidLoseOutputSurfaceWithDelayBasedBeginFrameSource) { | 2764 TEST_F(SchedulerTest, DidLoseOutputSurfaceWithDelayBasedBeginFrameSource) { |
2383 SetUpScheduler(true); | 2765 SetUpScheduler(true); |
2384 | 2766 |
2385 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. | 2767 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
2386 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 2768 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
2387 scheduler_->SetNeedsBeginMainFrame(); | 2769 scheduler_->SetNeedsBeginMainFrame(); |
2388 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 2770 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
2389 | 2771 |
2390 client_->Reset(); | 2772 client_->Reset(); |
2391 AdvanceFrame(); | 2773 AdvanceFrame(); |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3305 } | 3687 } |
3306 | 3688 |
3307 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { | 3689 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { |
3308 EXPECT_FALSE(BeginMainFrameOnCriticalPath( | 3690 EXPECT_FALSE(BeginMainFrameOnCriticalPath( |
3309 SMOOTHNESS_TAKES_PRIORITY, | 3691 SMOOTHNESS_TAKES_PRIORITY, |
3310 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); | 3692 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); |
3311 } | 3693 } |
3312 | 3694 |
3313 } // namespace | 3695 } // namespace |
3314 } // namespace cc | 3696 } // namespace cc |
OLD | NEW |