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