Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / cc / surfaces / display_scheduler_unittest.cc
blob7fedbc77c64519b0d5146f9b41ce1206b0fda0a2
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/surfaces/display_scheduler.h"
7 #include "base/logging.h"
8 #include "base/test/null_task_runner.h"
9 #include "base/trace_event/trace_event.h"
10 #include "cc/output/begin_frame_args.h"
11 #include "cc/surfaces/display.h"
12 #include "cc/test/scheduler_test_common.h"
13 #include "cc/test/test_now_source.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace cc {
17 namespace {
19 class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
20 public:
21 FakeDisplaySchedulerClient() : draw_and_swap_count_(0) {}
23 ~FakeDisplaySchedulerClient() override {}
25 bool DrawAndSwap() override {
26 draw_and_swap_count_++;
27 return true;
30 void Reset() { draw_and_swap_count_ = 0; }
32 int draw_and_swap_count() const { return draw_and_swap_count_; }
34 protected:
35 int draw_and_swap_count_;
38 class TestDisplayScheduler : public DisplayScheduler {
39 public:
40 TestDisplayScheduler(DisplaySchedulerClient* client,
41 BeginFrameSource* begin_frame_source,
42 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
43 int max_pending_swaps)
44 : DisplayScheduler(client,
45 begin_frame_source,
46 task_runner,
47 max_pending_swaps),
48 scheduler_begin_frame_deadline_count_(0) {}
50 base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
51 return DesiredBeginFrameDeadlineTime();
54 void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); }
56 void ScheduleBeginFrameDeadline() override {
57 scheduler_begin_frame_deadline_count_++;
58 DisplayScheduler::ScheduleBeginFrameDeadline();
61 int scheduler_begin_frame_deadline_count() {
62 return scheduler_begin_frame_deadline_count_;
65 protected:
66 int scheduler_begin_frame_deadline_count_;
69 class DisplaySchedulerTest : public testing::Test {
70 public:
71 DisplaySchedulerTest() {
72 const int max_pending_swaps = 1;
73 now_src_ = TestNowSource::Create();
74 null_task_runner_ = make_scoped_refptr(new base::NullTaskRunner);
75 client_ = make_scoped_ptr(new FakeDisplaySchedulerClient);
76 scheduler_ = make_scoped_ptr(
77 new TestDisplayScheduler(client_.get(), &fake_begin_frame_source_,
78 null_task_runner_, max_pending_swaps));
81 ~DisplaySchedulerTest() override {}
83 void SetUp() override { scheduler_->SetRootSurfaceResourcesLocked(false); }
85 void BeginFrameForTest() {
86 base::TimeTicks frame_time = now_src_->Now();
87 base::TimeDelta interval = BeginFrameArgs::DefaultInterval();
88 base::TimeTicks deadline = frame_time + interval -
89 BeginFrameArgs::DefaultEstimatedParentDrawTime();
90 fake_begin_frame_source_.TestOnBeginFrame(
91 BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
92 interval, BeginFrameArgs::NORMAL));
95 protected:
96 TestNowSource& now_src() { return *now_src_; }
97 FakeDisplaySchedulerClient& client() { return *client_; }
98 DisplayScheduler& scheduler() { return *scheduler_; }
100 scoped_refptr<TestNowSource> now_src_;
101 scoped_refptr<base::NullTaskRunner> null_task_runner_;
103 FakeBeginFrameSource fake_begin_frame_source_;
104 scoped_ptr<FakeDisplaySchedulerClient> client_;
105 scoped_ptr<TestDisplayScheduler> scheduler_;
108 TEST_F(DisplaySchedulerTest, EntireDisplayDamagedDrawsImmediately) {
109 SurfaceId root_surface_id(1);
110 BeginFrameForTest();
111 EXPECT_LT(now_src().Now(),
112 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
113 scheduler_->EntireDisplayDamaged(root_surface_id);
114 EXPECT_GE(now_src().Now(),
115 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
118 TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
119 SurfaceId root_surface_id(0);
120 SurfaceId sid1(1);
121 SurfaceId sid2(2);
123 // Set the root surface
124 scheduler_->EntireDisplayDamaged(root_surface_id);
126 // Get scheduler to detect surface 1 as active by drawing
127 // two frames in a row with damage from surface 1.
128 BeginFrameForTest();
129 scheduler_->SurfaceDamaged(sid1);
130 scheduler_->BeginFrameDeadlineForTest();
131 BeginFrameForTest();
132 scheduler_->SurfaceDamaged(sid1);
133 scheduler_->BeginFrameDeadlineForTest();
135 // Damage only from surface 2 (inactive) does not trigger deadline early.
136 BeginFrameForTest();
137 scheduler_->SurfaceDamaged(sid2);
138 EXPECT_LT(now_src().Now(),
139 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
141 // Damage from surface 1 triggers deadline early.
142 scheduler_->SurfaceDamaged(sid1);
143 EXPECT_GE(now_src().Now(),
144 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
145 scheduler_->BeginFrameDeadlineForTest();
147 // Make both surface 1 and 2 active.
148 BeginFrameForTest();
149 scheduler_->SurfaceDamaged(sid2);
150 scheduler_->SurfaceDamaged(sid1);
151 scheduler_->BeginFrameDeadlineForTest();
153 // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
154 BeginFrameForTest();
155 EXPECT_LT(now_src().Now(),
156 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
157 scheduler_->SurfaceDamaged(sid1);
158 EXPECT_LT(now_src().Now(),
159 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
160 scheduler_->SurfaceDamaged(sid2);
161 EXPECT_GE(now_src().Now(),
162 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
163 scheduler_->BeginFrameDeadlineForTest();
165 // Make the system idle
166 BeginFrameForTest();
167 scheduler_->BeginFrameDeadlineForTest();
168 BeginFrameForTest();
169 scheduler_->BeginFrameDeadlineForTest();
171 // Deadline should trigger early if child surfaces are idle and
172 // we get damage on the root surface.
173 BeginFrameForTest();
174 EXPECT_LT(now_src().Now(),
175 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
176 scheduler_->SurfaceDamaged(root_surface_id);
177 EXPECT_GE(now_src().Now(),
178 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
179 scheduler_->BeginFrameDeadlineForTest();
182 TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
183 SurfaceId sid1(1);
185 // DrawAndSwap normally.
186 BeginFrameForTest();
187 EXPECT_LT(now_src().Now(),
188 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
189 EXPECT_EQ(0, client_->draw_and_swap_count());
190 scheduler_->SurfaceDamaged(sid1);
191 scheduler_->BeginFrameDeadlineForTest();
192 EXPECT_EQ(1, client_->draw_and_swap_count());
194 // Deadline triggers immediately on OutputSurfaceLost.
195 BeginFrameForTest();
196 EXPECT_LT(now_src().Now(),
197 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
198 scheduler_->OutputSurfaceLost();
199 EXPECT_GE(now_src().Now(),
200 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
202 // Deadline does not DrawAndSwap after OutputSurfaceLost.
203 EXPECT_EQ(1, client_->draw_and_swap_count());
204 scheduler_->SurfaceDamaged(sid1);
205 scheduler_->BeginFrameDeadlineForTest();
206 EXPECT_EQ(1, client_->draw_and_swap_count());
209 TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) {
210 SurfaceId sid1(1);
211 base::TimeTicks late_deadline;
213 // DrawAndSwap normally.
214 BeginFrameForTest();
215 EXPECT_LT(now_src().Now(),
216 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
217 EXPECT_EQ(0, client_->draw_and_swap_count());
218 scheduler_->SurfaceDamaged(sid1);
219 scheduler_->BeginFrameDeadlineForTest();
220 EXPECT_EQ(1, client_->draw_and_swap_count());
222 // Deadline triggers late while root resources are locked.
223 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
224 BeginFrameForTest();
225 scheduler_->SurfaceDamaged(sid1);
226 EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
227 scheduler_->SetRootSurfaceResourcesLocked(true);
228 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
230 // Deadline does not DrawAndSwap while root resources are locked.
231 EXPECT_EQ(1, client_->draw_and_swap_count());
232 scheduler_->SurfaceDamaged(sid1);
233 scheduler_->BeginFrameDeadlineForTest();
234 EXPECT_EQ(1, client_->draw_and_swap_count());
236 // Deadline triggers normally when root resources are unlocked.
237 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
238 BeginFrameForTest();
239 scheduler_->SurfaceDamaged(sid1);
240 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
241 scheduler_->SetRootSurfaceResourcesLocked(false);
242 EXPECT_EQ(base::TimeTicks(),
243 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
245 EXPECT_EQ(1, client_->draw_and_swap_count());
246 scheduler_->BeginFrameDeadlineForTest();
247 EXPECT_EQ(2, client_->draw_and_swap_count());
250 TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
251 SurfaceId sid1(1);
252 SurfaceId sid2(2);
253 base::TimeTicks late_deadline;
255 // Get scheduler to detect surface 1 and 2 as active.
256 BeginFrameForTest();
257 scheduler_->SurfaceDamaged(sid1);
258 scheduler_->SurfaceDamaged(sid2);
259 scheduler_->BeginFrameDeadlineForTest();
260 BeginFrameForTest();
261 scheduler_->SurfaceDamaged(sid1);
262 scheduler_->SurfaceDamaged(sid2);
263 scheduler_->BeginFrameDeadlineForTest();
265 // DrawAndSwap normally.
266 BeginFrameForTest();
267 EXPECT_LT(now_src().Now(),
268 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
269 EXPECT_EQ(2, client_->draw_and_swap_count());
270 scheduler_->SurfaceDamaged(sid1);
271 scheduler_->SurfaceDamaged(sid2);
272 scheduler_->BeginFrameDeadlineForTest();
273 EXPECT_EQ(3, client_->draw_and_swap_count());
274 scheduler_->DidSwapBuffers();
276 // Deadline triggers early when swap throttled.
277 BeginFrameForTest();
278 // Damage surface 1, but not surface 2 so we avoid triggering deadline
279 // early because all surfaces are ready.
280 scheduler_->SurfaceDamaged(sid1);
281 EXPECT_EQ(scheduler_->DesiredBeginFrameDeadlineTimeForTest(),
282 base::TimeTicks());
284 // Don't draw and swap in deadline while swap throttled.
285 EXPECT_EQ(3, client_->draw_and_swap_count());
286 scheduler_->BeginFrameDeadlineForTest();
287 EXPECT_EQ(3, client_->draw_and_swap_count());
289 // Deadline triggers normally once not swap throttled.
290 // Damage from previous BeginFrame should cary over, so don't damage again.
291 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
292 scheduler_->DidSwapBuffersComplete();
293 BeginFrameForTest();
294 EXPECT_GT(scheduler_->DesiredBeginFrameDeadlineTimeForTest(),
295 now_src().Now());
296 EXPECT_LT(scheduler_->DesiredBeginFrameDeadlineTimeForTest(), late_deadline);
297 // Still waiting for surface 2. Once it updates, deadline should trigger
298 // immediately again.
299 scheduler_->SurfaceDamaged(sid2);
300 EXPECT_EQ(scheduler_->DesiredBeginFrameDeadlineTimeForTest(),
301 base::TimeTicks());
302 // Draw and swap now that we aren't throttled.
303 EXPECT_EQ(3, client_->draw_and_swap_count());
304 scheduler_->BeginFrameDeadlineForTest();
305 EXPECT_EQ(4, client_->draw_and_swap_count());
308 // This test verfies that we try to reschedule the deadline
309 // after any event that may change what deadline we want.
310 TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
311 SurfaceId root_surface_id(1);
312 SurfaceId sid1(2);
313 int count = 1;
314 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
316 BeginFrameForTest();
317 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
319 scheduler_->BeginFrameDeadlineForTest();
320 scheduler_->DidSwapBuffers();
321 BeginFrameForTest();
322 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
324 scheduler_->DidSwapBuffersComplete();
325 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
327 scheduler_->EntireDisplayDamaged(root_surface_id);
328 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
330 scheduler_->SurfaceDamaged(sid1);
331 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
333 scheduler_->SetRootSurfaceResourcesLocked(true);
334 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
336 scheduler_->OutputSurfaceLost();
337 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
340 } // namespace
341 } // namespace cc