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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 371 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
382 client_->Reset(); | 372 client_->Reset(); |
383 } | 373 } |
384 | 374 |
385 // As this function contains EXPECT macros, to allow debugging it should be | 375 // As this function contains EXPECT macros, to allow debugging it should be |
386 // called inside EXPECT_SCOPED like so; | 376 // called inside EXPECT_SCOPED like so; |
387 // EXPECT_SCOPED(client.AdvanceFrame()); | 377 // EXPECT_SCOPED(client.AdvanceFrame()); |
388 void AdvanceFrame() { | 378 void AdvanceFrame() { |
389 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), | 379 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), |
390 "FakeSchedulerClient::AdvanceFrame"); | 380 "FakeSchedulerClient::AdvanceFrame"); |
| 381 // Consume any previous deadline first, if no deadline is currently |
| 382 // pending, InsideBeginImplFrame will return false straight away and we |
| 383 // will run no tasks. |
| 384 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 385 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
391 | 386 |
392 // Send the next BeginFrame message if using an external source, otherwise | 387 // Send the next BeginFrame message if using an external source, otherwise |
393 // it will be already in the task queue. | 388 // it will be already in the task queue. |
394 if (scheduler_->begin_frame_source() == | 389 if (scheduler_->begin_frame_source() == |
395 fake_external_begin_frame_source_.get()) { | 390 fake_external_begin_frame_source_.get()) { |
396 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 391 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
397 SendNextBeginFrame(); | 392 SendNextBeginFrame(); |
398 } else { | 393 } |
399 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); | 394 |
| 395 if (!scheduler_->settings().using_synchronous_renderer_compositor) { |
| 396 // Then run tasks until new deadline is scheduled. |
| 397 EXPECT_TRUE( |
| 398 task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 399 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
400 } | 400 } |
401 } | 401 } |
402 | 402 |
403 BeginFrameArgs SendNextBeginFrame() { | 403 BeginFrameArgs SendNextBeginFrame() { |
404 DCHECK_EQ(scheduler_->begin_frame_source(), | 404 DCHECK_EQ(scheduler_->begin_frame_source(), |
405 fake_external_begin_frame_source_.get()); | 405 fake_external_begin_frame_source_.get()); |
406 // Creep the time forward so that any BeginFrameArgs is not equal to the | 406 // Creep the time forward so that any BeginFrameArgs is not equal to the |
407 // last one otherwise we violate the BeginFrameSource contract. | 407 // last one otherwise we violate the BeginFrameSource contract. |
408 now_src_->Advance(BeginFrameArgs::DefaultInterval()); | 408 now_src_->Advance(BeginFrameArgs::DefaultInterval()); |
409 BeginFrameArgs args = | 409 BeginFrameArgs args = |
(...skipping 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2001 EXPECT_NO_ACTION(client_); | 2001 EXPECT_NO_ACTION(client_); |
2002 | 2002 |
2003 // Activate the pending tree, which also unblocks the commit immediately | 2003 // Activate the pending tree, which also unblocks the commit immediately |
2004 // while we are in an idle state. | 2004 // while we are in an idle state. |
2005 client_->Reset(); | 2005 client_->Reset(); |
2006 scheduler_->NotifyReadyToActivate(); | 2006 scheduler_->NotifyReadyToActivate(); |
2007 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); | 2007 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 0, 2); |
2008 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); | 2008 EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); |
2009 } | 2009 } |
2010 | 2010 |
| 2011 TEST_F(SchedulerTest, BeginRetroFrame) { |
| 2012 SetUpScheduler(EXTERNAL_BFS); |
| 2013 |
| 2014 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2015 scheduler_->SetNeedsBeginMainFrame(); |
| 2016 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2017 client_->Reset(); |
| 2018 |
| 2019 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2020 // This is the first BeginFrame, which will be handled immediately. |
| 2021 BeginFrameArgs args = |
| 2022 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2023 args.deadline += base::TimeDelta::FromHours(1); |
| 2024 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2025 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2026 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2027 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2028 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2029 client_->Reset(); |
| 2030 |
| 2031 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2032 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2033 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2034 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2035 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2036 |
| 2037 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2038 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2039 EXPECT_NO_ACTION(client_); |
| 2040 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2041 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2042 client_->Reset(); |
| 2043 |
| 2044 // NotifyReadyToCommit should trigger the commit. |
| 2045 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2046 scheduler_->NotifyReadyToCommit(); |
| 2047 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2048 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2049 client_->Reset(); |
| 2050 |
| 2051 // NotifyReadyToActivate should trigger the activation. |
| 2052 scheduler_->NotifyReadyToActivate(); |
| 2053 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2054 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2055 client_->Reset(); |
| 2056 |
| 2057 // BeginImplFrame should prepare the draw. |
| 2058 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2059 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2060 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2061 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2062 client_->Reset(); |
| 2063 |
| 2064 // BeginImplFrame deadline should draw. |
| 2065 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2066 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2067 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2068 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2069 client_->Reset(); |
| 2070 |
| 2071 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) |
| 2072 // to avoid excessive toggles. |
| 2073 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2074 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
| 2075 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2076 client_->Reset(); |
| 2077 |
| 2078 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2079 EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); |
| 2080 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); |
| 2081 client_->Reset(); |
| 2082 } |
| 2083 |
| 2084 TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { |
| 2085 SetUpScheduler(EXTERNAL_BFS); |
| 2086 |
| 2087 scheduler_->SetNeedsBeginMainFrame(); |
| 2088 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2089 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2090 |
| 2091 client_->Reset(); |
| 2092 EXPECT_SCOPED(AdvanceFrame()); |
| 2093 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2094 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2095 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2096 |
| 2097 client_->Reset(); |
| 2098 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2099 |
| 2100 client_->Reset(); |
| 2101 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
| 2102 // This BeginFrame is queued up as a retro frame. |
| 2103 EXPECT_NO_ACTION(client_); |
| 2104 // The previous deadline is still pending. |
| 2105 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2106 |
| 2107 client_->Reset(); |
| 2108 // This main frame activating should schedule the (previous) deadline to |
| 2109 // trigger immediately. |
| 2110 scheduler_->NotifyReadyToCommit(); |
| 2111 scheduler_->NotifyReadyToActivate(); |
| 2112 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); |
| 2113 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); |
| 2114 |
| 2115 client_->Reset(); |
| 2116 // The deadline task should trigger causing a draw. |
| 2117 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2118 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2119 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2120 |
| 2121 // Keep animating. |
| 2122 client_->Reset(); |
| 2123 scheduler_->SetNeedsOneBeginImplFrame(); |
| 2124 scheduler_->SetNeedsRedraw(); |
| 2125 EXPECT_NO_ACTION(client_); |
| 2126 |
| 2127 // Let's advance to the retro frame's deadline. |
| 2128 now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks()); |
| 2129 |
| 2130 // The retro frame hasn't expired yet. |
| 2131 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false)); |
| 2132 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2133 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2134 |
| 2135 // This is an immediate deadline case. |
| 2136 client_->Reset(); |
| 2137 task_runner().RunPendingTasks(); |
| 2138 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2139 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); |
| 2140 } |
| 2141 |
| 2142 TEST_F(SchedulerTest, RetroFrameExpiresOnTime) { |
| 2143 SetUpScheduler(EXTERNAL_BFS); |
| 2144 |
| 2145 scheduler_->SetNeedsBeginMainFrame(); |
| 2146 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2147 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2148 |
| 2149 client_->Reset(); |
| 2150 EXPECT_SCOPED(AdvanceFrame()); |
| 2151 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2152 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2153 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2154 |
| 2155 client_->Reset(); |
| 2156 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2157 |
| 2158 client_->Reset(); |
| 2159 BeginFrameArgs retro_frame_args = SendNextBeginFrame(); |
| 2160 // This BeginFrame is queued up as a retro frame. |
| 2161 EXPECT_NO_ACTION(client_); |
| 2162 // The previous deadline is still pending. |
| 2163 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2164 |
| 2165 client_->Reset(); |
| 2166 // This main frame activating should schedule the (previous) deadline to |
| 2167 // trigger immediately. |
| 2168 scheduler_->NotifyReadyToCommit(); |
| 2169 scheduler_->NotifyReadyToActivate(); |
| 2170 EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); |
| 2171 EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); |
| 2172 |
| 2173 client_->Reset(); |
| 2174 // The deadline task should trigger causing a draw. |
| 2175 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2176 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2177 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
| 2178 |
| 2179 // Keep animating. |
| 2180 client_->Reset(); |
| 2181 scheduler_->SetNeedsOneBeginImplFrame(); |
| 2182 scheduler_->SetNeedsRedraw(); |
| 2183 EXPECT_NO_ACTION(client_); |
| 2184 |
| 2185 // Let's advance sufficiently past the retro frame's deadline. |
| 2186 now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks() + |
| 2187 base::TimeDelta::FromMicroseconds(1)); |
| 2188 |
| 2189 // The retro frame should've expired. |
| 2190 EXPECT_NO_ACTION(client_); |
| 2191 } |
| 2192 |
| 2193 TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) { |
| 2194 SetUpScheduler(EXTERNAL_BFS); |
| 2195 |
| 2196 scheduler_->SetNeedsBeginMainFrame(); |
| 2197 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2198 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2199 |
| 2200 BeginFrameArgs missed_frame_args = |
| 2201 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2202 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 2203 |
| 2204 // Advance to the deadline. |
| 2205 now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks()); |
| 2206 |
| 2207 // Missed frame is handled because it's on time. |
| 2208 client_->Reset(); |
| 2209 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 2210 EXPECT_TRUE( |
| 2211 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 2212 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2213 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2214 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2215 } |
| 2216 |
| 2217 TEST_F(SchedulerTest, MissedFrameExpiresOnTime) { |
| 2218 SetUpScheduler(EXTERNAL_BFS); |
| 2219 |
| 2220 scheduler_->SetNeedsBeginMainFrame(); |
| 2221 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2222 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2223 |
| 2224 BeginFrameArgs missed_frame_args = |
| 2225 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2226 missed_frame_args.type = BeginFrameArgs::MISSED; |
| 2227 |
| 2228 // Advance sufficiently past the deadline. |
| 2229 now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks() + |
| 2230 base::TimeDelta::FromMicroseconds(1)); |
| 2231 |
| 2232 // Missed frame is dropped because it's too late. |
| 2233 client_->Reset(); |
| 2234 fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); |
| 2235 EXPECT_FALSE( |
| 2236 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); |
| 2237 EXPECT_NO_ACTION(client_); |
| 2238 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2239 } |
| 2240 |
2011 void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) { | 2241 void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) { |
2012 SetUpScheduler(bfs_type); | 2242 SetUpScheduler(bfs_type); |
2013 | 2243 |
2014 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame | 2244 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame |
2015 // without calling SetNeedsBeginFrame. | 2245 // without calling SetNeedsBeginFrame. |
2016 scheduler_->SetNeedsBeginMainFrame(); | 2246 scheduler_->SetNeedsBeginMainFrame(); |
2017 EXPECT_NO_ACTION(client_); | 2247 EXPECT_NO_ACTION(client_); |
2018 client_->Reset(); | 2248 client_->Reset(); |
2019 | 2249 |
2020 EXPECT_SCOPED(AdvanceFrame()); | 2250 // When the client-driven BeginFrame are disabled, the scheduler posts it's |
2021 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 2251 // own BeginFrame tasks. |
2022 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 2252 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
2023 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | 2253 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
2024 client_->Reset(); | 2254 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
2025 | 2255 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2026 // Can't run the deadline task because it can race with begin frame for the | 2256 client_->Reset(); |
2027 // SyntheticBFS case. | 2257 |
2028 EXPECT_SCOPED(AdvanceFrame()); | 2258 // If we don't swap on the deadline, we wait for the next BeginFrame. |
| 2259 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2260 EXPECT_NO_ACTION(client_); |
| 2261 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2262 client_->Reset(); |
| 2263 |
| 2264 // NotifyReadyToCommit should trigger the commit. |
| 2265 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2266 scheduler_->NotifyReadyToCommit(); |
| 2267 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2268 client_->Reset(); |
| 2269 |
| 2270 // NotifyReadyToActivate should trigger the activation. |
| 2271 scheduler_->NotifyReadyToActivate(); |
| 2272 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2273 client_->Reset(); |
| 2274 |
| 2275 // BeginImplFrame should prepare the draw. |
| 2276 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
2029 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | 2277 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
2030 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | 2278 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2031 client_->Reset(); | 2279 client_->Reset(); |
2032 | 2280 |
2033 // NotifyReadyToCommit should trigger the commit. | 2281 // BeginImplFrame deadline should draw. |
2034 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); | 2282 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
2035 scheduler_->NotifyReadyToCommit(); | 2283 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
2036 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 2284 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
2037 client_->Reset(); | 2285 client_->Reset(); |
2038 | 2286 |
2039 // NotifyReadyToActivate should trigger the activation. | 2287 // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) |
2040 scheduler_->NotifyReadyToActivate(); | 2288 // to avoid excessive toggles. |
2041 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); | 2289 task_runner().RunPendingTasks(); // Run posted BeginFrame. |
2042 client_->Reset(); | 2290 EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); |
2043 | 2291 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
2044 // BeginImplFrame deadline should draw. The following BeginImplFrame deadline | |
2045 // should SetNeedsBeginFrame(false) to avoid excessive toggles. | |
2046 EXPECT_SCOPED(AdvanceFrame()); | |
2047 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); | |
2048 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); | |
2049 client_->Reset(); | 2292 client_->Reset(); |
2050 | 2293 |
2051 // Make sure SetNeedsBeginFrame isn't called on the client | 2294 // Make sure SetNeedsBeginFrame isn't called on the client |
2052 // when the BeginFrame is no longer needed. | 2295 // when the BeginFrame is no longer needed. |
2053 task_runner().RunPendingTasks(); // Run posted deadline. | 2296 task_runner().RunPendingTasks(); // Run posted deadline. |
2054 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); | 2297 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); |
2055 client_->Reset(); | 2298 client_->Reset(); |
2056 } | 2299 } |
2057 | 2300 |
2058 TEST_F(SchedulerTest, SyntheticBeginFrames) { | 2301 TEST_F(SchedulerTest, SyntheticBeginFrames) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 | 2549 |
2307 client_->Reset(); | 2550 client_->Reset(); |
2308 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); | 2551 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
2309 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); | 2552 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); |
2310 EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 1, | 2553 EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 1, |
2311 4); | 2554 4); |
2312 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); | 2555 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); |
2313 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); | 2556 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); |
2314 } | 2557 } |
2315 | 2558 |
| 2559 TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterBeginRetroFramePosted) { |
| 2560 SetUpScheduler(EXTERNAL_BFS); |
| 2561 |
| 2562 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2563 scheduler_->SetNeedsBeginMainFrame(); |
| 2564 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2565 |
| 2566 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2567 // This is the first BeginFrame, which will be handled immediately. |
| 2568 client_->Reset(); |
| 2569 BeginFrameArgs args = |
| 2570 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2571 args.deadline += base::TimeDelta::FromHours(1); |
| 2572 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2573 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2574 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2575 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2576 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2577 |
| 2578 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2579 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2580 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2581 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2582 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2583 |
| 2584 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2585 client_->Reset(); |
| 2586 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2587 EXPECT_NO_ACTION(client_); |
| 2588 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2589 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2590 |
| 2591 // NotifyReadyToCommit should trigger the commit. |
| 2592 client_->Reset(); |
| 2593 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2594 scheduler_->NotifyReadyToCommit(); |
| 2595 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2596 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2597 |
| 2598 // NotifyReadyToActivate should trigger the activation. |
| 2599 client_->Reset(); |
| 2600 scheduler_->NotifyReadyToActivate(); |
| 2601 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2602 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2603 |
| 2604 client_->Reset(); |
| 2605 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2606 scheduler_->DidLoseCompositorFrameSink(); |
| 2607 EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0, |
| 2608 3); |
| 2609 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); |
| 2610 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
| 2611 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2612 |
| 2613 // Posted BeginRetroFrame is aborted. |
| 2614 client_->Reset(); |
| 2615 task_runner().RunPendingTasks(); |
| 2616 EXPECT_NO_ACTION(client_); |
| 2617 } |
| 2618 |
| 2619 TEST_F(SchedulerTest, DidLoseCompositorFrameSinkDuringBeginRetroFrameRunning) { |
| 2620 SetUpScheduler(EXTERNAL_BFS); |
| 2621 |
| 2622 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2623 scheduler_->SetNeedsBeginMainFrame(); |
| 2624 EXPECT_SINGLE_ACTION("AddObserver(this)", client_); |
| 2625 |
| 2626 // Create a BeginFrame with a long deadline to avoid race conditions. |
| 2627 // This is the first BeginFrame, which will be handled immediately. |
| 2628 client_->Reset(); |
| 2629 BeginFrameArgs args = |
| 2630 CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); |
| 2631 args.deadline += base::TimeDelta::FromHours(1); |
| 2632 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2633 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2634 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2635 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2636 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2637 |
| 2638 // Queue BeginFrames while we are still handling the previous BeginFrame. |
| 2639 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2640 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2641 args.frame_time += base::TimeDelta::FromSeconds(1); |
| 2642 fake_external_begin_frame_source()->TestOnBeginFrame(args); |
| 2643 |
| 2644 // If we don't swap on the deadline, we wait for the next BeginImplFrame. |
| 2645 client_->Reset(); |
| 2646 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2647 EXPECT_NO_ACTION(client_); |
| 2648 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2649 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2650 |
| 2651 // NotifyReadyToCommit should trigger the commit. |
| 2652 client_->Reset(); |
| 2653 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2654 scheduler_->NotifyReadyToCommit(); |
| 2655 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2656 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2657 |
| 2658 // NotifyReadyToActivate should trigger the activation. |
| 2659 client_->Reset(); |
| 2660 scheduler_->NotifyReadyToActivate(); |
| 2661 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2662 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2663 |
| 2664 // BeginImplFrame should prepare the draw. |
| 2665 client_->Reset(); |
| 2666 task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. |
| 2667 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2668 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2669 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2670 |
| 2671 client_->Reset(); |
| 2672 EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2673 scheduler_->DidLoseCompositorFrameSink(); |
| 2674 EXPECT_NO_ACTION(client_); |
| 2675 EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); |
| 2676 |
| 2677 // BeginImplFrame deadline should abort drawing. |
| 2678 client_->Reset(); |
| 2679 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2680 EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0, |
| 2681 3); |
| 2682 EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); |
| 2683 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); |
| 2684 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); |
| 2685 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
| 2686 |
| 2687 // No more BeginRetroFrame because BeginRetroFrame queue is cleared. |
| 2688 client_->Reset(); |
| 2689 task_runner().RunPendingTasks(); |
| 2690 EXPECT_NO_ACTION(client_); |
| 2691 } |
| 2692 |
2316 TEST_F(SchedulerTest, | 2693 TEST_F(SchedulerTest, |
2317 DidLoseCompositorFrameSinkWithDelayBasedBeginFrameSource) { | 2694 DidLoseCompositorFrameSinkWithDelayBasedBeginFrameSource) { |
2318 SetUpScheduler(THROTTLED_BFS); | 2695 SetUpScheduler(THROTTLED_BFS); |
2319 | 2696 |
2320 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. | 2697 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
2321 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 2698 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
2322 scheduler_->SetNeedsBeginMainFrame(); | 2699 scheduler_->SetNeedsBeginMainFrame(); |
2323 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 2700 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
2324 | 2701 |
2325 client_->Reset(); | 2702 client_->Reset(); |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3228 } | 3605 } |
3229 | 3606 |
3230 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { | 3607 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { |
3231 EXPECT_FALSE(BeginMainFrameOnCriticalPath( | 3608 EXPECT_FALSE(BeginMainFrameOnCriticalPath( |
3232 SMOOTHNESS_TAKES_PRIORITY, | 3609 SMOOTHNESS_TAKES_PRIORITY, |
3233 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); | 3610 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); |
3234 } | 3611 } |
3235 | 3612 |
3236 } // namespace | 3613 } // namespace |
3237 } // namespace cc | 3614 } // namespace cc |
OLD | NEW |