1 // Copyright 2019 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/metrics/average_lag_tracker.h"
6
7 #include <memory>
8
9 #include "base/test/metrics/histogram_tester.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 using base::Bucket;
14 using testing::ElementsAre;
15
16 namespace cc {
17 namespace {
18
19 class AverageLagTrackerTest : public testing::Test {
20 public:
AverageLagTrackerTest()21 AverageLagTrackerTest() { ResetHistograms(); }
22
ResetHistograms()23 void ResetHistograms() {
24 histogram_tester_ = std::make_unique<base::HistogramTester>();
25 }
26
histogram_tester()27 const base::HistogramTester& histogram_tester() { return *histogram_tester_; }
28
SetUp()29 void SetUp() override {
30 average_lag_tracker_gpu_swap_ = std::make_unique<AverageLagTracker>(
31 AverageLagTracker::FinishTimeType::GpuSwapBegin);
32 average_lag_tracker_presentation_ = std::make_unique<AverageLagTracker>(
33 AverageLagTracker::FinishTimeType::PresentationFeedback);
34 }
35
SyntheticTouchScrollBegin(base::TimeTicks event_time,base::TimeTicks frame_time,float delta,float predicted_delta=0)36 void SyntheticTouchScrollBegin(base::TimeTicks event_time,
37 base::TimeTicks frame_time,
38 float delta,
39 float predicted_delta = 0) {
40 AverageLagTracker::EventInfo event_info(
41 0, delta, predicted_delta != 0 ? predicted_delta : delta, event_time,
42 AverageLagTracker::EventType::ScrollBegin);
43 event_info.finish_timestamp = frame_time;
44
45 // Always add the events to both and test if they have the same behavior
46 // regardless of the metrics names.
47 average_lag_tracker_gpu_swap_->AddScrollEventInFrame(event_info);
48 average_lag_tracker_presentation_->AddScrollEventInFrame(event_info);
49 }
50
SyntheticTouchScrollUpdate(base::TimeTicks event_time,base::TimeTicks frame_time,float delta,float predicted_delta=0)51 void SyntheticTouchScrollUpdate(base::TimeTicks event_time,
52 base::TimeTicks frame_time,
53 float delta,
54 float predicted_delta = 0) {
55 AverageLagTracker::EventInfo event_info(
56 0, delta, predicted_delta != 0 ? predicted_delta : delta, event_time,
57 AverageLagTracker::EventType::ScrollUpdate);
58 event_info.finish_timestamp = frame_time;
59
60 average_lag_tracker_gpu_swap_->AddScrollEventInFrame(event_info);
61 average_lag_tracker_presentation_->AddScrollEventInFrame(event_info);
62 }
63
CheckScrollBeginHistograms(int bucket_value,int count)64 void CheckScrollBeginHistograms(int bucket_value, int count) {
65 EXPECT_THAT(histogram_tester().GetAllSamples(
66 "Event.Latency.ScrollBegin.Touch.AverageLag"),
67 ElementsAre(Bucket(bucket_value, count)));
68 EXPECT_THAT(histogram_tester().GetAllSamples(
69 "Event.Latency.ScrollBegin.Touch.AverageLagPresentation"),
70 ElementsAre(Bucket(bucket_value, count)));
71 }
72
CheckScrollUpdateHistograms(int bucket_value,int count)73 void CheckScrollUpdateHistograms(int bucket_value, int count) {
74 EXPECT_THAT(histogram_tester().GetAllSamples(
75 "Event.Latency.ScrollUpdate.Touch.AverageLag"),
76 ElementsAre(Bucket(bucket_value, count)));
77
78 EXPECT_THAT(histogram_tester().GetAllSamples(
79 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation"),
80 ElementsAre(Bucket(bucket_value, count)));
81 }
82
CheckPredictionPositiveHistograms(int bucket_value,int count)83 void CheckPredictionPositiveHistograms(int bucket_value, int count) {
84 EXPECT_THAT(
85 histogram_tester().GetAllSamples(
86 "Event.Latency.ScrollUpdate.Touch.AverageLag.PredictionPositive"),
87 ElementsAre(Bucket(bucket_value, count)));
88
89 EXPECT_THAT(histogram_tester().GetAllSamples(
90 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation."
91 "PredictionPositive"),
92 ElementsAre(Bucket(bucket_value, count)));
93 }
94
CheckPredictionNegativeHistograms(int bucket_value,int count)95 void CheckPredictionNegativeHistograms(int bucket_value, int count) {
96 EXPECT_THAT(
97 histogram_tester().GetAllSamples(
98 "Event.Latency.ScrollUpdate.Touch.AverageLag.PredictionNegative"),
99 ElementsAre(Bucket(bucket_value, count)));
100
101 EXPECT_THAT(histogram_tester().GetAllSamples(
102 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation."
103 "PredictionNegative"),
104 ElementsAre(Bucket(bucket_value, count)));
105 }
106
CheckScrollUpdateHistogramsTotalCount(int count)107 void CheckScrollUpdateHistogramsTotalCount(int count) {
108 histogram_tester().ExpectTotalCount(
109 "Event.Latency.ScrollUpdate.Touch.AverageLag", count);
110 histogram_tester().ExpectTotalCount(
111 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation", count);
112 }
113
CheckPredictionPositiveHistogramsTotalCount(int count)114 void CheckPredictionPositiveHistogramsTotalCount(int count) {
115 histogram_tester().ExpectTotalCount(
116 "Event.Latency.ScrollUpdate.Touch.AverageLag.PredictionPositive",
117 count);
118 histogram_tester().ExpectTotalCount(
119 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation."
120 "PredictionPositive",
121 count);
122 }
123
CheckPredictionNegativeHistogramsTotalCount(int count)124 void CheckPredictionNegativeHistogramsTotalCount(int count) {
125 histogram_tester().ExpectTotalCount(
126 "Event.Latency.ScrollUpdate.Touch.AverageLag.PredictionNegative",
127 count);
128 histogram_tester().ExpectTotalCount(
129 "Event.Latency.ScrollUpdate.Touch.AverageLagPresentation."
130 "PredictionNegative",
131 count);
132 }
133
134 protected:
135 std::unique_ptr<AverageLagTracker> average_lag_tracker_gpu_swap_;
136 std::unique_ptr<AverageLagTracker> average_lag_tracker_presentation_;
137
138 std::unique_ptr<base::HistogramTester> histogram_tester_;
139 };
140
MillisecondsToTimeTicks(float t_ms)141 base::TimeTicks MillisecondsToTimeTicks(float t_ms) {
142 return base::TimeTicks() + base::TimeDelta::FromMilliseconds(t_ms);
143 }
144
145 // Simulate a simple situation that events at every 10ms and start at t=15ms,
146 // frame swaps at every 10ms too and start at t=20ms and test we record one
147 // UMA for ScrollUpdate in one second.
TEST_F(AverageLagTrackerTest,OneSecondInterval)148 TEST_F(AverageLagTrackerTest, OneSecondInterval) {
149 base::TimeTicks event_time =
150 base::TimeTicks() + base::TimeDelta::FromMilliseconds(5);
151 base::TimeTicks frame_time =
152 base::TimeTicks() + base::TimeDelta::FromMilliseconds(10);
153 float scroll_delta = 10;
154
155 // ScrollBegin
156 event_time += base::TimeDelta::FromMilliseconds(10); // 15ms
157 frame_time += base::TimeDelta::FromMilliseconds(10); // 20ms
158 SyntheticTouchScrollBegin(event_time, frame_time, scroll_delta);
159
160 // Send 101 ScrollUpdate events to verify that there is 1 AverageLag record
161 // per 1 second.
162 const int kUpdates = 101;
163 for (int i = 0; i < kUpdates; i++) {
164 event_time += base::TimeDelta::FromMilliseconds(10);
165 frame_time += base::TimeDelta::FromMilliseconds(10);
166 // First 50 has positive delta, others negetive delta.
167 const int sign = (i < kUpdates / 2) ? 1 : -1;
168 SyntheticTouchScrollUpdate(event_time, frame_time, sign * scroll_delta);
169 }
170
171 // ScrollBegin report_time is at 20ms, so the next ScrollUpdate report_time is
172 // at 1020ms. The last event_time that finish this report should be later than
173 // 1020ms.
174 EXPECT_EQ(event_time,
175 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1025));
176 EXPECT_EQ(frame_time,
177 base::TimeTicks() + base::TimeDelta::FromMilliseconds(1030));
178
179 // ScrollBegin AverageLag are the area between the event original component
180 // (time=15ms, delta=10px) to the frame swap time (time=20ms, expect finger
181 // position at delta=15px). The AverageLag scaled to 1 second is
182 // (0.5*(10px+15px)*5ms)/5ms = 12.5px.
183 CheckScrollBeginHistograms(12, 1);
184
185 // This ScrollUpdate AverageLag are calculated as the finger uniformly scroll
186 // 10px each frame. For scroll up/down frame, the Lag at the last frame swap
187 // is 5px, and Lag at this frame swap is 15px. For the one changing direction,
188 // the Lag is from 5 to 10 and down to 5 again. So total LagArea is 99 * 100,
189 // plus 75. the AverageLag in 1 second is 9.975px.
190 CheckScrollUpdateHistograms(9, 1);
191 CheckPredictionPositiveHistograms(0, 1);
192 CheckPredictionNegativeHistogramsTotalCount(0);
193
194 ResetHistograms();
195
196 // Send another ScrollBegin to end the unfinished ScrollUpdate report.
197 event_time += base::TimeDelta::FromMilliseconds(10);
198 frame_time += base::TimeDelta::FromMilliseconds(10);
199 SyntheticTouchScrollBegin(event_time, frame_time, scroll_delta);
200
201 // The last ScrollUpdate's lag is 8.75px and truncated to 8.
202 CheckScrollUpdateHistograms(8, 1);
203 CheckPredictionPositiveHistograms(0, 1);
204 CheckPredictionNegativeHistogramsTotalCount(0);
205 }
206
207 // Test the case that event's frame swap time is later than next event's
208 // creation time. (i.e, event at t=10ms will be dispatch at t=30ms, while next
209 // event is at t=20ms).
TEST_F(AverageLagTrackerTest,LargerLatency)210 TEST_F(AverageLagTrackerTest, LargerLatency) {
211 base::TimeTicks event_time = MillisecondsToTimeTicks(10);
212 base::TimeTicks frame_time =
213 event_time + base::TimeDelta::FromMilliseconds(20);
214 float scroll_delta = 10;
215
216 SyntheticTouchScrollBegin(event_time, frame_time, scroll_delta);
217
218 // Send 2 ScrollUpdate. The second one will record AverageLag.ScrollBegin as
219 // it's event_time is larger or equal to ScrollBegin's frame_time.
220 for (int i = 0; i < 2; i++) {
221 event_time += base::TimeDelta::FromMilliseconds(10);
222 frame_time = event_time + base::TimeDelta::FromMilliseconds(20);
223 SyntheticTouchScrollUpdate(event_time, frame_time, scroll_delta);
224 }
225
226 // ScrollBegin AveragLag are from t=10ms to t=30ms, with absolute scroll
227 // position from 10 to 30. The AverageLag should be:
228 // (0.5*(10px + 30px)*20ms/20ms) = 20px.
229 CheckScrollBeginHistograms(20, 1);
230
231 // Another ScrollBegin to flush unfinished frames.
232 // event_time doesn't matter here because the previous frames' lag are
233 // compute from their frame_time.
234 event_time = MillisecondsToTimeTicks(1000);
235 frame_time = MillisecondsToTimeTicks(1000);
236 SyntheticTouchScrollBegin(event_time, frame_time, scroll_delta);
237 // The to unfinished frames' lag are (finger_positon-rendered_position)*time,
238 // AverageLag is ((30px-10px)*10ms+(30px-20px)*10ms)/20ms = 15px.
239 CheckScrollUpdateHistograms(14, 1);
240 }
241
242 // Test that multiple latency being flush in the same frame swap.
TEST_F(AverageLagTrackerTest,TwoLatencyInfoInSameFrame)243 TEST_F(AverageLagTrackerTest, TwoLatencyInfoInSameFrame) {
244 // ScrollBegin
245 base::TimeTicks event_time = MillisecondsToTimeTicks(10);
246 base::TimeTicks frame_time = MillisecondsToTimeTicks(20);
247 SyntheticTouchScrollBegin(event_time, frame_time, -10 /* scroll_delta */);
248
249 // ScrollUpdate with event_time >= ScrollBegin frame_time will generate
250 // a histogram for AverageLag.ScrollBegin.
251 event_time = MillisecondsToTimeTicks(20);
252 frame_time = MillisecondsToTimeTicks(30);
253 SyntheticTouchScrollUpdate(event_time, frame_time, -10 /* scroll_delta */);
254
255 // Absolute position from -10 to -20. The AverageLag should be:
256 // (0.5*(10px + 20px)*10ms/10ms) = 15px.
257 CheckScrollBeginHistograms(14, 1);
258
259 event_time = MillisecondsToTimeTicks(25);
260 frame_time = MillisecondsToTimeTicks(30);
261 SyntheticTouchScrollUpdate(event_time, frame_time, 5 /* scroll_delta */);
262
263 // Another ScrollBegin to flush unfinished frames.
264 event_time = MillisecondsToTimeTicks(1000);
265 frame_time = MillisecondsToTimeTicks(1000);
266 SyntheticTouchScrollBegin(event_time, frame_time, 0);
267
268 // The ScrollUpdates are at t=20ms, finger_pos=-20px, rendered_pos=-10px,
269 // at t=25ms, finger_pos=-15px, rendered_pos=-10px;
270 // To t=30ms both events get flush.
271 // AverageLag is (0.5*(10px+5px)*5ms + 5px*5ms)/10ms = 6.25px
272 CheckScrollUpdateHistograms(6, 1);
273 }
274
275 // Test the case that switching direction causes lag at current frame
276 // time and previous frame time are in different direction.
TEST_F(AverageLagTrackerTest,ChangeDirectionInFrame)277 TEST_F(AverageLagTrackerTest, ChangeDirectionInFrame) {
278 // ScrollBegin
279 base::TimeTicks event_time = MillisecondsToTimeTicks(10);
280 base::TimeTicks frame_time = MillisecondsToTimeTicks(20);
281 SyntheticTouchScrollBegin(event_time, frame_time, 10 /* scroll_delta */);
282
283 // At t=20, lag = 10px.
284 event_time = MillisecondsToTimeTicks(20);
285 frame_time = MillisecondsToTimeTicks(30);
286 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */);
287
288 // At t=30, lag = -10px.
289 event_time = MillisecondsToTimeTicks(30);
290 frame_time = MillisecondsToTimeTicks(40);
291 SyntheticTouchScrollUpdate(event_time, frame_time, -20 /* scroll_delta */);
292
293 // Another ScrollBegin to flush unfinished frames.
294 event_time = MillisecondsToTimeTicks(1000);
295 frame_time = MillisecondsToTimeTicks(1000);
296 SyntheticTouchScrollBegin(event_time, frame_time, 0);
297
298 // From t=20 to t=30, lag_area=2*(0.5*10px*5ms)=50px*ms.
299 // From t=30 to t=40, lag_area=20px*10ms=200px*ms
300 // AverageLag = (50+200)/20 = 12.5px.
301 CheckScrollUpdateHistograms(12, 1);
302 }
303
304 // A simple case without scroll prediction to compare with the two with
305 // prediction cases below.
TEST_F(AverageLagTrackerTest,NoScrollPrediction)306 TEST_F(AverageLagTrackerTest, NoScrollPrediction) {
307 // ScrollBegin, at t=5, finger_pos=5px.
308 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
309 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
310 SyntheticTouchScrollBegin(event_time, frame_time, 5 /* scroll_delta */);
311
312 // ScrollUpdate, at t=15, finger_pos=15px.
313 event_time = MillisecondsToTimeTicks(15);
314 frame_time = MillisecondsToTimeTicks(20);
315 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */);
316
317 // ScrollUpdate, at t=25, finger_pos=25px.
318 event_time = MillisecondsToTimeTicks(25);
319 frame_time = MillisecondsToTimeTicks(30);
320 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */);
321
322 // Another ScrollBegin to flush unfinished frames.
323 event_time = MillisecondsToTimeTicks(1000);
324 frame_time = MillisecondsToTimeTicks(1000);
325 SyntheticTouchScrollBegin(event_time, frame_time, 0);
326
327 // Prediction hasn't take affect on ScrollBegin so it'll stay the same.
328 CheckScrollBeginHistograms(7, 1);
329 // At t=10, finger_pos = 10px, rendered_pos = 5px.
330 // At t=20, finger_pos = 20px, rendered_pos = 15px.
331 // At t=30, finger_pos = 25px, rendered_pos = 25px.
332 // AverageLag = ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
333 // = 9.375
334 CheckScrollUpdateHistograms(9, 1);
335 }
336
337 // Test AverageLag with perfect scroll prediction.
TEST_F(AverageLagTrackerTest,ScrollPrediction)338 TEST_F(AverageLagTrackerTest, ScrollPrediction) {
339 // ScrollBegin, at t=5, finger_pos=5px.
340 // Predict frame_time=10, predicted_pos = 10px.
341 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
342 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
343 SyntheticTouchScrollBegin(event_time, frame_time, 5 /* scroll_delta */,
344 10 /* predicted_delta */);
345
346 // ScrollUpdate, at t=15, finger_pos=15px.
347 // Predict frame_time=20, predicted_pos = 20px.
348 event_time = MillisecondsToTimeTicks(15);
349 frame_time = MillisecondsToTimeTicks(20);
350 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
351 10 /* predicted_delta */);
352
353 // ScrollUpdate, at t=25, finger_pos=25px.
354 // Predict frame_time=30, predicted_pos = 30px.
355 event_time = MillisecondsToTimeTicks(25);
356 frame_time = MillisecondsToTimeTicks(30);
357 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
358 10 /* predicted_delta */);
359
360 // Another ScrollBegin to flush unfinished frames.
361 event_time = MillisecondsToTimeTicks(1000);
362 frame_time = MillisecondsToTimeTicks(1000);
363 SyntheticTouchScrollBegin(event_time, frame_time, 0);
364
365 // Prediction hasn't take affect on ScrollBegin so it'll stay the same.
366 CheckScrollBeginHistograms(7, 1);
367 // At t=10, finger_pos = 10px, rendered_pos = 10px.
368 // At t=20, finger_pos = 20px, rendered_pos = 20px.
369 // At t=30, finger_pos = 25px, rendered_pos = 30px.
370 // AverageLag = ((0px+10px)*10ms/2 + (0px+5px)*10ms/2 + 5px*5ms)/20ms
371 // = 4.375px
372 // AverageLag (w/o prediction)
373 // ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
374 // = 9.375px
375 // Positive effect of prediction = 5px
376 CheckScrollUpdateHistograms(4, 1);
377 CheckPredictionPositiveHistograms(5, 1);
378 CheckPredictionNegativeHistogramsTotalCount(0);
379 }
380
381 // Test AverageLag with imperfect scroll prediction.
TEST_F(AverageLagTrackerTest,ImperfectScrollPrediction)382 TEST_F(AverageLagTrackerTest, ImperfectScrollPrediction) {
383 // ScrollBegin, at t=5, finger_pos=5px.
384 // Predict frame_time=10, predicted_pos(over) = 12px.
385 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
386 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
387 SyntheticTouchScrollBegin(event_time, frame_time, 5 /* scroll_delta */,
388 12 /* predicted_delta */);
389
390 // ScrollUpdate, at t=15, finger_pos=15px.
391 // Predict frame_time=20, predicted_pos(under) = 17px.
392 event_time = MillisecondsToTimeTicks(15);
393 frame_time = MillisecondsToTimeTicks(20);
394 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
395 5 /* predicted_delta */);
396
397 // ScrollUpdate, at t=25, finger_pos=25px.
398 // Predict frame_time=30, predicted_pos(over) = 31px.
399 event_time = MillisecondsToTimeTicks(25);
400 frame_time = MillisecondsToTimeTicks(30);
401 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
402 14 /* predicted_delta */);
403
404 // Another ScrollBegin to flush unfinished frames.
405 event_time = MillisecondsToTimeTicks(1000);
406 frame_time = MillisecondsToTimeTicks(1000);
407 SyntheticTouchScrollBegin(event_time, frame_time, 0);
408
409 CheckScrollBeginHistograms(7, 1);
410 // AverageLag = ((2px*2ms/2+8px*8ms/2)+ ((3px+8px)*5ms/2+8px*5ms))/20ms
411 // = 5.075px
412 CheckScrollUpdateHistograms(5, 1);
413 // AverageLag (w/o prediction =
414 // ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
415 // = 9.375px
416 // Positive effect of prediction = 4.3px
417 CheckPredictionPositiveHistograms(4, 1);
418 CheckPredictionNegativeHistogramsTotalCount(0);
419 }
420
TEST_F(AverageLagTrackerTest,NegativePredictionEffect)421 TEST_F(AverageLagTrackerTest, NegativePredictionEffect) {
422 // ScrollBegin, at t=5, finger_pos=5px.
423 // Predict frame_time=10, predicted_pos(over) = 20px.
424 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
425 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
426 SyntheticTouchScrollBegin(event_time, frame_time, 5 /* scroll_delta */,
427 20 /* predicted_delta */);
428
429 // ScrollUpdate, at t=15, finger_pos=15px.
430 // Predict frame_time=20, predicted_pos(over) = 60px.
431 event_time = MillisecondsToTimeTicks(15);
432 frame_time = MillisecondsToTimeTicks(20);
433 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
434 40 /* predicted_delta */);
435
436 // ScrollUpdate, at t=25, finger_pos=25px.
437 // Predict frame_time=30, predicted_pos(over) = 60px.
438 event_time = MillisecondsToTimeTicks(25);
439 frame_time = MillisecondsToTimeTicks(30);
440 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
441 0 /* predicted_delta */);
442
443 // Another ScrollBegin to flush unfinished frames.
444 event_time = MillisecondsToTimeTicks(1000);
445 frame_time = MillisecondsToTimeTicks(1000);
446 SyntheticTouchScrollBegin(event_time, frame_time, 0);
447
448 CheckScrollBeginHistograms(7, 1);
449 // AverageLag = ((10px+0px)*10ms/2)+ ((40px+35px)*5ms/2+35px*5ms))/20ms
450 // = 20.625px
451 CheckScrollUpdateHistograms(20, 1);
452 // AverageLag (w/o prediction =
453 // ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
454 // = 9.375px
455 // Negative effect of prediction = 11.25
456 CheckPredictionPositiveHistogramsTotalCount(0);
457 CheckPredictionNegativeHistograms(11, 1);
458 }
459
TEST_F(AverageLagTrackerTest,NoPredictionEffect)460 TEST_F(AverageLagTrackerTest, NoPredictionEffect) {
461 // ScrollBegin, at t=5, finger_pos=5px.
462 // Predict frame_time=10, predicted_pos(over) = 25px.
463 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
464 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
465 SyntheticTouchScrollBegin(event_time, frame_time, 5 /* scroll_delta */,
466 25 /* predicted_delta */);
467
468 // ScrollUpdate, at t=15, finger_pos=15px.
469 // Predict frame_time=20, predicted_pos(over) = 32px.
470 event_time = MillisecondsToTimeTicks(15);
471 frame_time = MillisecondsToTimeTicks(20);
472 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
473 7 /* predicted_delta */);
474
475 // ScrollUpdate, at t=25, finger_pos=25px.
476 // Predict frame_time=30, predicted_pos(over) = 37px.
477 event_time = MillisecondsToTimeTicks(25);
478 frame_time = MillisecondsToTimeTicks(30);
479 SyntheticTouchScrollUpdate(event_time, frame_time, 10 /* scroll_delta */,
480 5 /* predicted_delta */);
481
482 // Another ScrollBegin to flush unfinished frames.
483 event_time = MillisecondsToTimeTicks(1000);
484 frame_time = MillisecondsToTimeTicks(1000);
485 SyntheticTouchScrollBegin(event_time, frame_time, 0);
486
487 CheckScrollBeginHistograms(7, 1);
488 // AverageLag = ((15px+5px)*10ms/2 + (12px+7px)*5ms/2 + 7px*5ms)/20ms
489 // = 9.125px
490 CheckScrollUpdateHistograms(9, 1);
491 // AverageLag (w/o prediction) =
492 // ((5px+15px)*10ms/2 + (5px+10px)*5ms/2 + 10px*5ms)/20ms
493 // = 9.375px
494 // Prediction slightly positive, we should see a 0 bucket in
495 // PredictionPositive UMA
496 CheckPredictionPositiveHistograms(0, 1);
497 CheckPredictionNegativeHistogramsTotalCount(0);
498 }
499
500 // Tests that when an event arrives out-of-order, the average lag tracker
501 // properly ignores it.
TEST_F(AverageLagTrackerTest,EventOutOfOrder)502 TEST_F(AverageLagTrackerTest, EventOutOfOrder) {
503 base::TimeTicks event_time = MillisecondsToTimeTicks(5);
504 base::TimeTicks frame_time = MillisecondsToTimeTicks(10);
505 float scroll_delta = 5.f;
506 SyntheticTouchScrollBegin(event_time, frame_time, scroll_delta);
507
508 event_time = MillisecondsToTimeTicks(15);
509 frame_time = MillisecondsToTimeTicks(20);
510 SyntheticTouchScrollUpdate(event_time, frame_time, scroll_delta);
511
512 event_time = MillisecondsToTimeTicks(25);
513 frame_time = MillisecondsToTimeTicks(30);
514 SyntheticTouchScrollUpdate(event_time, frame_time, scroll_delta);
515
516 // A ScrollBegin to flush unfinished frames.
517 event_time = MillisecondsToTimeTicks(1000);
518 frame_time = MillisecondsToTimeTicks(1000);
519 SyntheticTouchScrollBegin(event_time, frame_time, 0);
520
521 CheckScrollUpdateHistogramsTotalCount(1);
522
523 // Send an event whose timestamp is earlier than the most recent event,
524 // representing an event that gets process out of order.
525 base::TimeTicks earlier_event_time = MillisecondsToTimeTicks(15);
526 frame_time = MillisecondsToTimeTicks(1010);
527 SyntheticTouchScrollUpdate(earlier_event_time, frame_time, scroll_delta);
528
529 // Another ScrollBegin to flush unfinished frames.
530 event_time = MillisecondsToTimeTicks(2000);
531 frame_time = MillisecondsToTimeTicks(2000);
532 SyntheticTouchScrollBegin(event_time, frame_time, 0);
533
534 // Ensure that the event was ignored.
535 CheckScrollUpdateHistogramsTotalCount(1);
536 }
537
538 } // namespace
539 } // namespace cc
540