| 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 |
| 185 void PushAction(const char* description) { | 195 void PushAction(const char* description) { |
| 186 actions_.push_back(description); | 196 actions_.push_back(description); |
| 187 states_.push_back(scheduler_->AsValue()); | 197 states_.push_back(scheduler_->AsValue()); |
| 188 } | 198 } |
| 189 | 199 |
| 190 // FakeExternalBeginFrameSource::Client implementation. | 200 // FakeExternalBeginFrameSource::Client implementation. |
| 191 void OnAddObserver(BeginFrameObserver* obs) override { | 201 void OnAddObserver(BeginFrameObserver* obs) override { |
| 192 PushAction("AddObserver(this)"); | 202 PushAction("AddObserver(this)"); |
| 193 } | 203 } |
| 194 void OnRemoveObserver(BeginFrameObserver* obs) override { | 204 void OnRemoveObserver(BeginFrameObserver* obs) override { |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 370 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
| 361 client_->Reset(); | 371 client_->Reset(); |
| 362 } | 372 } |
| 363 | 373 |
| 364 // As this function contains EXPECT macros, to allow debugging it should be | 374 // As this function contains EXPECT macros, to allow debugging it should be |
| 365 // called inside EXPECT_SCOPED like so; | 375 // called inside EXPECT_SCOPED like so; |
| 366 // EXPECT_SCOPED(client.AdvanceFrame()); | 376 // EXPECT_SCOPED(client.AdvanceFrame()); |
| 367 void AdvanceFrame() { | 377 void AdvanceFrame() { |
| 368 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), | 378 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), |
| 369 "FakeSchedulerClient::AdvanceFrame"); | 379 "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()); | |
| 375 | 380 |
| 376 // Send the next BeginFrame message if using an external source, otherwise | 381 // Send the next BeginFrame message if using an external source, otherwise |
| 377 // it will be already in the task queue. | 382 // it will be already in the task queue. |
| 378 if (scheduler_->begin_frame_source() == | 383 if (scheduler_->begin_frame_source() == |
| 379 fake_external_begin_frame_source_.get()) { | 384 fake_external_begin_frame_source_.get()) { |
| 380 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 385 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 381 SendNextBeginFrame(); | 386 SendNextBeginFrame(); |
| 382 } | 387 } else { |
| 383 | 388 task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); |
| 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 | |
| 2276 void SchedulerTest::BeginFramesNotFromClient( | 2041 void SchedulerTest::BeginFramesNotFromClient( |
| 2277 bool use_external_begin_frame_source, | 2042 bool use_external_begin_frame_source, |
| 2278 bool throttle_frame_production) { | 2043 bool throttle_frame_production) { |
| 2279 scheduler_settings_.use_external_begin_frame_source = | 2044 scheduler_settings_.use_external_begin_frame_source = |
| 2280 use_external_begin_frame_source; | 2045 use_external_begin_frame_source; |
| 2281 scheduler_settings_.throttle_frame_production = throttle_frame_production; | 2046 scheduler_settings_.throttle_frame_production = throttle_frame_production; |
| 2282 SetUpScheduler(true); | 2047 SetUpScheduler(true); |
| 2283 | 2048 |
| 2284 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame | 2049 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame |
| 2285 // without calling SetNeedsBeginFrame. | 2050 // without calling SetNeedsBeginFrame. |
| 2286 scheduler_->SetNeedsBeginMainFrame(); | 2051 scheduler_->SetNeedsBeginMainFrame(); |
| 2287 EXPECT_NO_ACTION(client_); | 2052 EXPECT_NO_ACTION(client_); |
| 2288 client_->Reset(); | 2053 client_->Reset(); |
| 2289 | 2054 |
| 2290 // When the client-driven BeginFrame are disabled, the scheduler posts it's | 2055 EXPECT_SCOPED(AdvanceFrame()); |
| 2291 // own BeginFrame tasks. | |
| 2292 task_runner().RunPendingTasks(); // Run posted BeginFrame. | |
| 2293 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 2056 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
| 2294 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 2057 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
| 2295 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | 2058 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2296 client_->Reset(); | 2059 client_->Reset(); |
| 2297 | 2060 |
| 2298 // If we don't swap on the deadline, we wait for the next BeginFrame. | 2061 // Can't run the deadline task because it can race with begin frame for the |
| 2299 task_runner().RunPendingTasks(); // Run posted deadline. | 2062 // SyntheticBFS case. |
| 2300 EXPECT_NO_ACTION(client_); | 2063 EXPECT_SCOPED(AdvanceFrame()); |
| 2301 EXPECT_FALSE(client_->IsInsideBeginImplFrame()); | 2064 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); |
| 2065 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); |
| 2302 client_->Reset(); | 2066 client_->Reset(); |
| 2303 | 2067 |
| 2304 // NotifyReadyToCommit should trigger the commit. | 2068 // NotifyReadyToCommit should trigger the commit. |
| 2305 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); | 2069 scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); |
| 2306 scheduler_->NotifyReadyToCommit(); | 2070 scheduler_->NotifyReadyToCommit(); |
| 2307 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); | 2071 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); |
| 2308 client_->Reset(); | 2072 client_->Reset(); |
| 2309 | 2073 |
| 2310 // NotifyReadyToActivate should trigger the activation. | 2074 // NotifyReadyToActivate should trigger the activation. |
| 2311 scheduler_->NotifyReadyToActivate(); | 2075 scheduler_->NotifyReadyToActivate(); |
| 2312 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); | 2076 EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); |
| 2313 client_->Reset(); | 2077 client_->Reset(); |
| 2314 | 2078 |
| 2315 // BeginImplFrame should prepare the draw. | 2079 // BeginImplFrame deadline should draw. The following BeginImplFrame deadline |
| 2316 task_runner().RunPendingTasks(); // Run posted BeginFrame. | 2080 // should SetNeedsBeginFrame(false) to avoid excessive toggles. |
| 2317 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); | 2081 EXPECT_SCOPED(AdvanceFrame()); |
| 2318 EXPECT_TRUE(client_->IsInsideBeginImplFrame()); | 2082 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); |
| 2319 client_->Reset(); | 2083 EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); |
| 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()); | |
| 2332 client_->Reset(); | 2084 client_->Reset(); |
| 2333 | 2085 |
| 2334 // Make sure SetNeedsBeginFrame isn't called on the client | 2086 // Make sure SetNeedsBeginFrame isn't called on the client |
| 2335 // when the BeginFrame is no longer needed. | 2087 // when the BeginFrame is no longer needed. |
| 2336 task_runner().RunPendingTasks(); // Run posted deadline. | 2088 task_runner().RunPendingTasks(); // Run posted deadline. |
| 2337 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); | 2089 EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_); |
| 2338 client_->Reset(); | 2090 client_->Reset(); |
| 2339 } | 2091 } |
| 2340 | 2092 |
| 2341 TEST_F(SchedulerTest, SyntheticBeginFrames) { | 2093 TEST_F(SchedulerTest, SyntheticBeginFrames) { |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2620 EXPECT_NO_ACTION(client_); | 2372 EXPECT_NO_ACTION(client_); |
| 2621 | 2373 |
| 2622 client_->Reset(); | 2374 client_->Reset(); |
| 2623 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); | 2375 task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); |
| 2624 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); | 2376 EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4); |
| 2625 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4); | 2377 EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4); |
| 2626 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); | 2378 EXPECT_ACTION("RemoveObserver(this)", client_, 2, 4); |
| 2627 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); | 2379 EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); |
| 2628 } | 2380 } |
| 2629 | 2381 |
| 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 | |
| 2764 TEST_F(SchedulerTest, DidLoseOutputSurfaceWithDelayBasedBeginFrameSource) { | 2382 TEST_F(SchedulerTest, DidLoseOutputSurfaceWithDelayBasedBeginFrameSource) { |
| 2765 SetUpScheduler(true); | 2383 SetUpScheduler(true); |
| 2766 | 2384 |
| 2767 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. | 2385 // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. |
| 2768 EXPECT_FALSE(scheduler_->begin_frames_expected()); | 2386 EXPECT_FALSE(scheduler_->begin_frames_expected()); |
| 2769 scheduler_->SetNeedsBeginMainFrame(); | 2387 scheduler_->SetNeedsBeginMainFrame(); |
| 2770 EXPECT_TRUE(scheduler_->begin_frames_expected()); | 2388 EXPECT_TRUE(scheduler_->begin_frames_expected()); |
| 2771 | 2389 |
| 2772 client_->Reset(); | 2390 client_->Reset(); |
| 2773 AdvanceFrame(); | 2391 AdvanceFrame(); |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3687 } | 3305 } |
| 3688 | 3306 |
| 3689 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { | 3307 TEST_F(SchedulerTest, BeginMainFrameOnCriticalPath_AHS) { |
| 3690 EXPECT_FALSE(BeginMainFrameOnCriticalPath( | 3308 EXPECT_FALSE(BeginMainFrameOnCriticalPath( |
| 3691 SMOOTHNESS_TAKES_PRIORITY, | 3309 SMOOTHNESS_TAKES_PRIORITY, |
| 3692 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); | 3310 ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER, kSlowDuration)); |
| 3693 } | 3311 } |
| 3694 | 3312 |
| 3695 } // namespace | 3313 } // namespace |
| 3696 } // namespace cc | 3314 } // namespace cc |
| OLD | NEW |