Wrapper script for isolating telemetry_gpu_unittests.
[chromium-blink-merge.git] / cc / surfaces / display_scheduler_unittest.cc
blobdee1225aca1ade598c5ae91809a2d9183f7775fc
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/test/simple_test_tick_clock.h"
10 #include "base/trace_event/trace_event.h"
11 #include "cc/output/begin_frame_args.h"
12 #include "cc/surfaces/display.h"
13 #include "cc/test/scheduler_test_common.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace cc {
17 namespace {
19 const int kMaxPendingSwaps = 1;
21 class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
22 public:
23 FakeDisplaySchedulerClient() : draw_and_swap_count_(0) {}
25 ~FakeDisplaySchedulerClient() override {}
27 bool DrawAndSwap() override {
28 draw_and_swap_count_++;
29 return true;
32 void Reset() { draw_and_swap_count_ = 0; }
34 int draw_and_swap_count() const { return draw_and_swap_count_; }
36 protected:
37 int draw_and_swap_count_;
40 class TestDisplayScheduler : public DisplayScheduler {
41 public:
42 TestDisplayScheduler(DisplaySchedulerClient* client,
43 BeginFrameSource* begin_frame_source,
44 base::SingleThreadTaskRunner* task_runner,
45 int max_pending_swaps)
46 : DisplayScheduler(client,
47 begin_frame_source,
48 task_runner,
49 max_pending_swaps),
50 scheduler_begin_frame_deadline_count_(0) {}
52 base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
53 return DesiredBeginFrameDeadlineTime();
56 void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); }
58 void ScheduleBeginFrameDeadline() override {
59 scheduler_begin_frame_deadline_count_++;
60 DisplayScheduler::ScheduleBeginFrameDeadline();
63 int scheduler_begin_frame_deadline_count() {
64 return scheduler_begin_frame_deadline_count_;
67 protected:
68 int scheduler_begin_frame_deadline_count_;
71 class DisplaySchedulerTest : public testing::Test {
72 public:
73 DisplaySchedulerTest()
74 : now_src_(new base::SimpleTestTickClock()),
75 task_runner_(new base::NullTaskRunner),
76 client_(new FakeDisplaySchedulerClient),
77 scheduler_(new TestDisplayScheduler(client_.get(),
78 &fake_begin_frame_source_,
79 task_runner_.get(),
80 kMaxPendingSwaps)) {
81 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
84 ~DisplaySchedulerTest() override {}
86 void SetUp() override { scheduler_->SetRootSurfaceResourcesLocked(false); }
88 void BeginFrameForTest() {
89 base::TimeTicks frame_time = now_src_->NowTicks();
90 base::TimeDelta interval = BeginFrameArgs::DefaultInterval();
91 base::TimeTicks deadline = frame_time + interval;
92 fake_begin_frame_source_.TestOnBeginFrame(
93 BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
94 interval, BeginFrameArgs::NORMAL));
97 protected:
98 base::SimpleTestTickClock& now_src() { return *now_src_; }
99 FakeDisplaySchedulerClient& client() { return *client_; }
100 DisplayScheduler& scheduler() { return *scheduler_; }
102 FakeBeginFrameSource fake_begin_frame_source_;
104 scoped_ptr<base::SimpleTestTickClock> now_src_;
105 scoped_refptr<base::NullTaskRunner> task_runner_;
106 scoped_ptr<FakeDisplaySchedulerClient> client_;
107 scoped_ptr<TestDisplayScheduler> scheduler_;
110 TEST_F(DisplaySchedulerTest, EntireDisplayDamagedDrawsImmediately) {
111 SurfaceId root_surface_id(1);
112 BeginFrameForTest();
113 EXPECT_LT(now_src().NowTicks(),
114 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
115 scheduler_->EntireDisplayDamaged(root_surface_id);
116 EXPECT_GE(now_src().NowTicks(),
117 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
120 TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
121 SurfaceId root_surface_id(0);
122 SurfaceId sid1(1);
123 SurfaceId sid2(2);
125 // Set the root surface
126 scheduler_->EntireDisplayDamaged(root_surface_id);
128 // Get scheduler to detect surface 1 as active by drawing
129 // two frames in a row with damage from surface 1.
130 BeginFrameForTest();
131 scheduler_->SurfaceDamaged(sid1);
132 scheduler_->BeginFrameDeadlineForTest();
133 BeginFrameForTest();
134 scheduler_->SurfaceDamaged(sid1);
135 scheduler_->BeginFrameDeadlineForTest();
137 // Damage only from surface 2 (inactive) does not trigger deadline early.
138 BeginFrameForTest();
139 scheduler_->SurfaceDamaged(sid2);
140 EXPECT_LT(now_src().NowTicks(),
141 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
143 // Damage from surface 1 triggers deadline early.
144 scheduler_->SurfaceDamaged(sid1);
145 EXPECT_GE(now_src().NowTicks(),
146 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
147 scheduler_->BeginFrameDeadlineForTest();
149 // Make both surface 1 and 2 active.
150 BeginFrameForTest();
151 scheduler_->SurfaceDamaged(sid2);
152 scheduler_->SurfaceDamaged(sid1);
153 scheduler_->BeginFrameDeadlineForTest();
155 // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
156 BeginFrameForTest();
157 EXPECT_LT(now_src().NowTicks(),
158 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
159 scheduler_->SurfaceDamaged(sid1);
160 EXPECT_LT(now_src().NowTicks(),
161 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
162 scheduler_->SurfaceDamaged(sid2);
163 EXPECT_GE(now_src().NowTicks(),
164 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
165 scheduler_->BeginFrameDeadlineForTest();
167 // Make the system idle
168 BeginFrameForTest();
169 scheduler_->BeginFrameDeadlineForTest();
170 BeginFrameForTest();
171 scheduler_->BeginFrameDeadlineForTest();
173 // Deadline should trigger early if child surfaces are idle and
174 // we get damage on the root surface.
175 BeginFrameForTest();
176 EXPECT_LT(now_src().NowTicks(),
177 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
178 scheduler_->SurfaceDamaged(root_surface_id);
179 EXPECT_GE(now_src().NowTicks(),
180 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
181 scheduler_->BeginFrameDeadlineForTest();
184 TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
185 SurfaceId sid1(1);
187 // DrawAndSwap normally.
188 BeginFrameForTest();
189 EXPECT_LT(now_src().NowTicks(),
190 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
191 EXPECT_EQ(0, client_->draw_and_swap_count());
192 scheduler_->SurfaceDamaged(sid1);
193 scheduler_->BeginFrameDeadlineForTest();
194 EXPECT_EQ(1, client_->draw_and_swap_count());
196 // Deadline triggers immediately on OutputSurfaceLost.
197 BeginFrameForTest();
198 EXPECT_LT(now_src().NowTicks(),
199 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
200 scheduler_->OutputSurfaceLost();
201 EXPECT_GE(now_src().NowTicks(),
202 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
204 // Deadline does not DrawAndSwap after OutputSurfaceLost.
205 EXPECT_EQ(1, client_->draw_and_swap_count());
206 scheduler_->SurfaceDamaged(sid1);
207 scheduler_->BeginFrameDeadlineForTest();
208 EXPECT_EQ(1, client_->draw_and_swap_count());
211 TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) {
212 SurfaceId sid1(1);
213 base::TimeTicks late_deadline;
215 // DrawAndSwap normally.
216 BeginFrameForTest();
217 EXPECT_LT(now_src().NowTicks(),
218 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
219 EXPECT_EQ(0, client_->draw_and_swap_count());
220 scheduler_->SurfaceDamaged(sid1);
221 scheduler_->BeginFrameDeadlineForTest();
222 EXPECT_EQ(1, client_->draw_and_swap_count());
224 // Deadline triggers late while root resources are locked.
225 late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
226 BeginFrameForTest();
227 scheduler_->SurfaceDamaged(sid1);
228 EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
229 scheduler_->SetRootSurfaceResourcesLocked(true);
230 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
232 // Deadline does not DrawAndSwap while root resources are locked.
233 EXPECT_EQ(1, client_->draw_and_swap_count());
234 scheduler_->SurfaceDamaged(sid1);
235 scheduler_->BeginFrameDeadlineForTest();
236 EXPECT_EQ(1, client_->draw_and_swap_count());
238 // Deadline triggers normally when root resources are unlocked.
239 late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
240 BeginFrameForTest();
241 scheduler_->SurfaceDamaged(sid1);
242 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
243 scheduler_->SetRootSurfaceResourcesLocked(false);
244 EXPECT_EQ(base::TimeTicks(),
245 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
247 EXPECT_EQ(1, client_->draw_and_swap_count());
248 scheduler_->BeginFrameDeadlineForTest();
249 EXPECT_EQ(2, client_->draw_and_swap_count());
252 TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
253 SurfaceId sid1(1);
254 SurfaceId sid2(2);
256 // Get scheduler to detect surface 1 and 2 as active.
257 BeginFrameForTest();
258 scheduler_->SurfaceDamaged(sid1);
259 scheduler_->SurfaceDamaged(sid2);
260 scheduler_->BeginFrameDeadlineForTest();
261 BeginFrameForTest();
262 scheduler_->SurfaceDamaged(sid1);
263 scheduler_->SurfaceDamaged(sid2);
264 scheduler_->BeginFrameDeadlineForTest();
266 // DrawAndSwap normally.
267 BeginFrameForTest();
268 EXPECT_LT(now_src().NowTicks(),
269 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
270 EXPECT_EQ(2, client_->draw_and_swap_count());
271 scheduler_->SurfaceDamaged(sid1);
272 scheduler_->SurfaceDamaged(sid2);
273 scheduler_->BeginFrameDeadlineForTest();
274 EXPECT_EQ(3, client_->draw_and_swap_count());
275 scheduler_->DidSwapBuffers();
277 // Deadline triggers late when swap throttled.
278 base::TimeTicks late_deadline =
279 now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
280 BeginFrameForTest();
281 // Damage surface 1, but not surface 2 so we avoid triggering deadline
282 // early because all surfaces are ready.
283 scheduler_->SurfaceDamaged(sid1);
284 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
286 // Don't draw and swap in deadline while swap throttled.
287 EXPECT_EQ(3, client_->draw_and_swap_count());
288 scheduler_->BeginFrameDeadlineForTest();
289 EXPECT_EQ(3, client_->draw_and_swap_count());
291 // Deadline triggers normally once not swap throttled.
292 // Damage from previous BeginFrame should cary over, so don't damage again.
293 base::TimeTicks expected_deadline =
294 fake_begin_frame_source_.TestLastUsedBeginFrameArgs().deadline -
295 BeginFrameArgs::DefaultEstimatedParentDrawTime();
296 scheduler_->DidSwapBuffersComplete();
297 BeginFrameForTest();
298 EXPECT_EQ(expected_deadline,
299 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
300 // Still waiting for surface 2. Once it updates, deadline should trigger
301 // immediately again.
302 scheduler_->SurfaceDamaged(sid2);
303 EXPECT_EQ(scheduler_->DesiredBeginFrameDeadlineTimeForTest(),
304 base::TimeTicks());
305 // Draw and swap now that we aren't throttled.
306 EXPECT_EQ(3, client_->draw_and_swap_count());
307 scheduler_->BeginFrameDeadlineForTest();
308 EXPECT_EQ(4, client_->draw_and_swap_count());
311 // This test verfies that we try to reschedule the deadline
312 // after any event that may change what deadline we want.
313 TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
314 SurfaceId root_surface_id(1);
315 SurfaceId sid1(2);
316 int count = 1;
317 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
319 BeginFrameForTest();
320 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
322 scheduler_->BeginFrameDeadlineForTest();
323 scheduler_->DidSwapBuffers();
324 BeginFrameForTest();
325 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
327 scheduler_->DidSwapBuffersComplete();
328 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
330 scheduler_->EntireDisplayDamaged(root_surface_id);
331 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
333 scheduler_->SurfaceDamaged(sid1);
334 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
336 scheduler_->SetRootSurfaceResourcesLocked(true);
337 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
339 scheduler_->OutputSurfaceLost();
340 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
343 } // namespace
344 } // namespace cc