Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: cc/surfaces/display_scheduler_unittest.cc

Issue 1012853003: Add DisplayScheduler for Surfaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: actually add unit tests Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "cc/surfaces/display_scheduler.h"
6
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"
15
16 namespace cc {
17 namespace {
18
19 class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
20 public:
21 FakeDisplaySchedulerClient() : draw_and_swap_count_(0) {}
22
23 ~FakeDisplaySchedulerClient() override {}
24
25 bool DrawAndSwap() override {
26 draw_and_swap_count_++;
27 return true;
28 }
29
30 void Reset() { draw_and_swap_count_ = 0; }
31
32 int draw_and_swap_count() const { return draw_and_swap_count_; }
33
34 protected:
35 int draw_and_swap_count_;
36 };
37
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) {}
49
50 base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
51 return DesiredBeginFrameDeadlineTime();
52 }
53
54 void BeginFrameDeadlineForTest() { OnBeginFrameDeadline(); }
55
56 void ScheduleBeginFrameDeadline() override {
57 scheduler_begin_frame_deadline_count_++;
58 DisplayScheduler::ScheduleBeginFrameDeadline();
59 }
60
61 int scheduler_begin_frame_deadline_count() {
62 return scheduler_begin_frame_deadline_count_;
63 }
64
65 protected:
66 int scheduler_begin_frame_deadline_count_;
67 };
68
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));
79 }
80
81 ~DisplaySchedulerTest() override {}
82
83 void SetUp() override { scheduler_->SetResourcesLockedByBrowser(false); }
84
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));
93 }
94
95 protected:
96 TestNowSource& now_src() { return *now_src_; }
97 FakeDisplaySchedulerClient& client() { return *client_; }
98 DisplayScheduler& scheduler() { return *scheduler_; }
99
100 scoped_refptr<TestNowSource> now_src_;
101 scoped_refptr<base::NullTaskRunner> null_task_runner_;
102
103 FakeBeginFrameSource fake_begin_frame_source_;
104 scoped_ptr<FakeDisplaySchedulerClient> client_;
105 scoped_ptr<TestDisplayScheduler> scheduler_;
106 };
107
108 TEST_F(DisplaySchedulerTest, EntireDisplayDamagedDrawsImmediately) {
109 BeginFrameForTest();
110 EXPECT_LT(now_src().Now(),
111 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
112 scheduler_->EntireDisplayDamaged();
113 EXPECT_GE(now_src().Now(),
114 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
115 }
116
117 TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
118 SurfaceId sid1(1);
119 SurfaceId sid2(2);
120
121 // Get scheduler to detect surface 1 as active by drawing
122 // two frames in a row with damage from surface 1.
123 BeginFrameForTest();
124 scheduler_->SurfaceDamaged(sid1);
125 scheduler_->BeginFrameDeadlineForTest();
126 BeginFrameForTest();
127 scheduler_->SurfaceDamaged(sid1);
128 scheduler_->BeginFrameDeadlineForTest();
129
130 // Damage only from surface 2 (inactive) does not trigger deadline early.
131 BeginFrameForTest();
132 scheduler_->SurfaceDamaged(sid2);
133 EXPECT_LT(now_src().Now(),
134 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
135
136 // Damage from surface 1 triggers deadline early.
137 scheduler_->SurfaceDamaged(sid1);
138 EXPECT_GE(now_src().Now(),
139 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
140 scheduler_->BeginFrameDeadlineForTest();
141
142 // Make both surface 1 and 2 active.
143 BeginFrameForTest();
144 scheduler_->SurfaceDamaged(sid2);
145 scheduler_->SurfaceDamaged(sid1);
146 scheduler_->BeginFrameDeadlineForTest();
147
148 // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
149 BeginFrameForTest();
150 EXPECT_LT(now_src().Now(),
151 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
152 scheduler_->SurfaceDamaged(sid1);
153 EXPECT_LT(now_src().Now(),
154 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
155 scheduler_->SurfaceDamaged(sid2);
156 EXPECT_GE(now_src().Now(),
157 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
158 scheduler_->BeginFrameDeadlineForTest();
159 }
160
161 TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
162 SurfaceId sid1(1);
163
164 // DrawAndSwap normally.
165 BeginFrameForTest();
166 EXPECT_LT(now_src().Now(),
167 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
168 EXPECT_EQ(0, client_->draw_and_swap_count());
169 scheduler_->SurfaceDamaged(sid1);
170 scheduler_->BeginFrameDeadlineForTest();
171 EXPECT_EQ(1, client_->draw_and_swap_count());
172
173 // Deadline triggers immediately on OutputSurfaceLost.
174 BeginFrameForTest();
175 EXPECT_LT(now_src().Now(),
176 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
177 scheduler_->OutputSurfaceLost();
178 EXPECT_GE(now_src().Now(),
179 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
180
181 // Deadline does not DrawAndSwap after OutputSurfaceLost.
182 EXPECT_EQ(1, client_->draw_and_swap_count());
183 scheduler_->SurfaceDamaged(sid1);
184 scheduler_->BeginFrameDeadlineForTest();
185 EXPECT_EQ(1, client_->draw_and_swap_count());
186 }
187
188 TEST_F(DisplaySchedulerTest, ResourcesLockedByBrowser) {
189 SurfaceId sid1(1);
190 base::TimeTicks late_deadline;
191
192 // DrawAndSwap normally.
193 BeginFrameForTest();
194 EXPECT_LT(now_src().Now(),
195 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
196 EXPECT_EQ(0, client_->draw_and_swap_count());
197 scheduler_->SurfaceDamaged(sid1);
198 scheduler_->BeginFrameDeadlineForTest();
199 EXPECT_EQ(1, client_->draw_and_swap_count());
200
201 // Deadline triggers late while ResourcesLockedByBrowser.
202 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
203 BeginFrameForTest();
204 scheduler_->SurfaceDamaged(sid1);
205 EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
206 scheduler_->SetResourcesLockedByBrowser(true);
207 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
208
209 // Deadline does not DrawAndSwap while ResourcesLockedByBrowser.
210 EXPECT_EQ(1, client_->draw_and_swap_count());
211 scheduler_->SurfaceDamaged(sid1);
212 scheduler_->BeginFrameDeadlineForTest();
213 // TODO(brianderson): Figure out why we need to draw to avoid hanging during
214 // normal operation here. Harmless, but seems fishy.
215 EXPECT_EQ(2, client_->draw_and_swap_count());
216
217 // Deadline triggers normally when ResourcesLockedByBrowser goes false.
218 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
219 BeginFrameForTest();
220 scheduler_->SurfaceDamaged(sid1);
221 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
222 scheduler_->SetResourcesLockedByBrowser(false);
223 EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
224 }
225
226 TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
227 SurfaceId sid1(1);
228 base::TimeTicks late_deadline;
229
230 // DrawAndSwap normally.
231 BeginFrameForTest();
232 EXPECT_LT(now_src().Now(),
233 scheduler_->DesiredBeginFrameDeadlineTimeForTest());
234 EXPECT_EQ(0, client_->draw_and_swap_count());
235 scheduler_->SurfaceDamaged(sid1);
236 scheduler_->BeginFrameDeadlineForTest();
237 EXPECT_EQ(1, client_->draw_and_swap_count());
238 scheduler_->DidSwapBuffers();
239
240 // Deadline triggers late while swap throttled.
241 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
242 BeginFrameForTest();
243 scheduler_->SurfaceDamaged(sid1);
244 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
245
246 // Don't draw and swap in deadline while swap throttled.
247 EXPECT_EQ(1, client_->draw_and_swap_count());
248 scheduler_->BeginFrameDeadlineForTest();
249 EXPECT_EQ(1, client_->draw_and_swap_count());
250
251 // Then triggers normally when once not swap throttled.
252 // Damage from previous BeginFrame should cary over, so don't damage again.
253 late_deadline = now_src().Now() + BeginFrameArgs::DefaultInterval();
254 BeginFrameForTest();
255 EXPECT_EQ(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
256 scheduler_->DidSwapBuffersComplete();
257 EXPECT_GT(late_deadline, scheduler_->DesiredBeginFrameDeadlineTimeForTest());
258
259 // Draw and swap in deadline now that we aren't swap throttled.
260 EXPECT_EQ(1, client_->draw_and_swap_count());
261 scheduler_->BeginFrameDeadlineForTest();
262 EXPECT_EQ(2, client_->draw_and_swap_count());
263 }
264
265 // This test verfies that we try to reschedule the deadline
266 // after any event that may change what deadline we want.
267 TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
268 SurfaceId sid1(1);
269 int count = 1;
270 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
271
272 BeginFrameForTest();
273 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
274
275 scheduler_->BeginFrameDeadlineForTest();
276 scheduler_->DidSwapBuffers();
277 BeginFrameForTest();
278 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
279
280 scheduler_->DidSwapBuffersComplete();
281 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
282
283 scheduler_->EntireDisplayDamaged();
284 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
285
286 scheduler_->SurfaceDamaged(sid1);
287 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
288
289 scheduler_->SetResourcesLockedByBrowser(true);
290 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
291
292 scheduler_->OutputSurfaceLost();
293 EXPECT_EQ(count++, scheduler_->scheduler_begin_frame_deadline_count());
294 }
295
296 } // namespace
297 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698