1 // Copyright 2015 The Chromium Authors
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/metrics/compositor_frame_reporting_controller.h"
11 #include "base/strings/strcat.h"
12 #include "base/test/metrics/histogram_tester.h"
13 #include "base/test/simple_test_tick_clock.h"
14 #include "base/time/time.h"
15 #include "cc/metrics/dropped_frame_counter.h"
16 #include "cc/metrics/event_metrics.h"
17 #include "cc/metrics/total_frame_counter.h"
18 #include "cc/scheduler/commit_earlyout_reason.h"
19 #include "components/viz/common/frame_timing_details.h"
20 #include "components/viz/common/quads/compositor_frame_metadata.h"
21 #include "testing/gmock/include/gmock/gmock.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "ui/events/types/scroll_input_type.h"
28 using ::testing::Each;
29 using ::testing::IsEmpty;
30 using ::testing::NotNull;
31 using SmoothEffectDrivingThread = FrameInfo::SmoothEffectDrivingThread;
33 class TestCompositorFrameReportingController
34 : public CompositorFrameReportingController {
36 TestCompositorFrameReportingController()
37 : CompositorFrameReportingController(/*should_report_histograms=*/true,
38 /*should_report_ukm=*/false,
39 /*layer_tree_host_id=*/1) {}
41 TestCompositorFrameReportingController(
42 const TestCompositorFrameReportingController& controller) = delete;
44 TestCompositorFrameReportingController& operator=(
45 const TestCompositorFrameReportingController& controller) = delete;
47 int ActiveReporters() {
49 for (int i = 0; i < PipelineStage::kNumPipelineStages; ++i) {
56 void ResetReporters() {
57 for (int i = 0; i < PipelineStage::kNumPipelineStages; ++i) {
58 reporters()[i] = nullptr;
62 size_t GetBlockingReportersCount() {
64 const PipelineStage kStages[] = {
65 PipelineStage::kBeginImplFrame,
66 PipelineStage::kBeginMainFrame,
67 PipelineStage::kCommit,
68 PipelineStage::kActivate,
70 for (auto stage : kStages) {
71 auto& reporter = reporters()[stage];
73 reporter->partial_update_dependents_size_for_testing() > 0) {
80 size_t GetBlockedReportersCount() {
82 const PipelineStage kStages[] = {
83 PipelineStage::kBeginImplFrame,
84 PipelineStage::kBeginMainFrame,
85 PipelineStage::kCommit,
86 PipelineStage::kActivate,
88 for (auto stage : kStages) {
89 auto& reporter = reporters()[stage];
91 count += reporter->partial_update_dependents_size_for_testing();
96 size_t GetAdoptedReportersCount() {
98 const PipelineStage kStages[] = {
99 PipelineStage::kBeginImplFrame,
100 PipelineStage::kBeginMainFrame,
101 PipelineStage::kCommit,
102 PipelineStage::kActivate,
104 for (auto stage : kStages) {
105 auto& reporter = reporters()[stage];
107 count += reporter->owned_partial_update_dependents_size_for_testing();
113 class CompositorFrameReportingControllerTest : public testing::Test {
115 CompositorFrameReportingControllerTest() : current_id_(1, 1) {
116 test_tick_clock_.SetNowTicks(base::TimeTicks::Now());
117 reporting_controller_.set_tick_clock(&test_tick_clock_);
118 args_ = SimulateBeginFrameArgs(current_id_);
119 reporting_controller_.SetDroppedFrameCounter(&dropped_counter_);
120 dropped_counter_.set_total_counter(&total_frame_counter_);
123 // The following functions simulate the actions that would
124 // occur for each phase of the reporting controller.
125 void SimulateBeginImplFrame() {
126 IncrementCurrentId();
127 begin_impl_time_ = AdvanceNowByMs(10);
128 reporting_controller_.WillBeginImplFrame(args_);
131 void SimulateBeginMainFrame() {
132 if (!reporting_controller_.reporters()[CompositorFrameReportingController::
133 PipelineStage::kBeginImplFrame])
134 SimulateBeginImplFrame();
136 reporting_controller_.reporters()[CompositorFrameReportingController::
137 PipelineStage::kBeginImplFrame]);
138 begin_main_time_ = AdvanceNowByMs(10);
139 reporting_controller_.WillBeginMainFrame(args_);
140 begin_main_start_time_ = AdvanceNowByMs(10);
143 void SimulateCommit(std::unique_ptr<BeginMainFrameMetrics> blink_breakdown) {
144 if (!reporting_controller_
145 .reporters()[CompositorFrameReportingController::PipelineStage::
147 SimulateBeginMainFrame();
150 reporting_controller_.reporters()[CompositorFrameReportingController::
151 PipelineStage::kBeginMainFrame]);
152 reporting_controller_.BeginMainFrameStarted(begin_main_start_time_);
153 reporting_controller_.NotifyReadyToCommit(std::move(blink_breakdown));
154 begin_commit_time_ = AdvanceNowByMs(10);
155 reporting_controller_.WillCommit();
156 end_commit_time_ = AdvanceNowByMs(10);
157 reporting_controller_.DidCommit();
160 void SimulateActivate() {
161 if (!reporting_controller_.reporters()
162 [CompositorFrameReportingController::PipelineStage::kCommit])
163 SimulateCommit(nullptr);
164 CHECK(reporting_controller_.reporters()
165 [CompositorFrameReportingController::PipelineStage::kCommit]);
166 begin_activation_time_ = AdvanceNowByMs(10);
167 reporting_controller_.WillActivate();
168 end_activation_time_ = AdvanceNowByMs(10);
169 reporting_controller_.DidActivate();
170 last_activated_id_ = current_id_;
173 void SimulateSubmitCompositorFrame(EventMetricsSet events_metrics) {
174 if (!reporting_controller_.reporters()
175 [CompositorFrameReportingController::PipelineStage::kActivate])
177 CHECK(reporting_controller_.reporters()
178 [CompositorFrameReportingController::PipelineStage::kActivate]);
179 submit_time_ = AdvanceNowByMs(10);
181 reporting_controller_.DidSubmitCompositorFrame(
182 *current_token_, submit_time_, current_id_, last_activated_id_,
183 std::move(events_metrics),
184 /*has_missing_content=*/false);
187 void SimulatePresentCompositorFrame() {
188 SimulateSubmitCompositorFrame({});
189 viz::FrameTimingDetails details = {};
190 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
191 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
194 viz::BeginFrameArgs SimulateBeginFrameArgs(viz::BeginFrameId frame_id) {
195 args_ = viz::BeginFrameArgs();
196 args_.frame_id = frame_id;
197 args_.frame_time = AdvanceNowByMs(10);
198 args_.interval = base::Milliseconds(16);
199 current_id_ = frame_id;
203 std::unique_ptr<BeginMainFrameMetrics> BuildBlinkBreakdown() {
204 auto breakdown = std::make_unique<BeginMainFrameMetrics>();
205 breakdown->handle_input_events = base::Microseconds(10);
206 breakdown->animate = base::Microseconds(9);
207 breakdown->style_update = base::Microseconds(8);
208 breakdown->layout_update = base::Microseconds(7);
209 breakdown->compositing_inputs = base::Microseconds(6);
210 breakdown->prepaint = base::Microseconds(5);
211 breakdown->paint = base::Microseconds(3);
212 breakdown->composite_commit = base::Microseconds(2);
213 breakdown->update_layers = base::Microseconds(1);
215 // Advance now by the sum of the breakdowns.
216 AdvanceNowByMs(10 + 9 + 8 + 7 + 6 + 5 + 3 + 2 + 1);
221 viz::FrameTimingDetails BuildVizBreakdown() {
222 viz::FrameTimingDetails viz_breakdown;
223 viz_breakdown.received_compositor_frame_timestamp = AdvanceNowByMs(1);
224 viz_breakdown.draw_start_timestamp = AdvanceNowByMs(2);
225 viz_breakdown.swap_timings.swap_start = AdvanceNowByMs(3);
226 viz_breakdown.swap_timings.swap_end = AdvanceNowByMs(4);
227 viz_breakdown.presentation_feedback.timestamp = AdvanceNowByMs(5);
228 return viz_breakdown;
231 void IncrementCurrentId() {
232 current_id_.sequence_number++;
233 args_.frame_id = current_id_;
236 base::TimeTicks AdvanceNowByMs(int64_t advance_ms) {
237 test_tick_clock_.Advance(base::Microseconds(advance_ms));
238 return test_tick_clock_.NowTicks();
241 std::unique_ptr<EventMetrics> SetupEventMetrics(
242 std::unique_ptr<EventMetrics> metrics) {
245 metrics->SetDispatchStageTimestamp(
246 EventMetrics::DispatchStage::kRendererCompositorStarted);
248 metrics->SetDispatchStageTimestamp(
249 EventMetrics::DispatchStage::kRendererCompositorFinished);
254 std::unique_ptr<EventMetrics> CreateEventMetrics(ui::EventType type) {
255 const base::TimeTicks event_time = AdvanceNowByMs(10);
257 return SetupEventMetrics(
258 EventMetrics::CreateForTesting(type, event_time, &test_tick_clock_));
261 std::unique_ptr<EventMetrics> CreateScrollBeginEventMetrics(
262 ui::ScrollInputType input_type) {
263 const base::TimeTicks event_time = AdvanceNowByMs(10);
264 const base::TimeTicks arrived_in_browser_main_timestamp = AdvanceNowByMs(3);
266 return SetupEventMetrics(ScrollEventMetrics::CreateForTesting(
267 ui::ET_GESTURE_SCROLL_BEGIN, input_type,
268 /*is_inertial=*/false, event_time, arrived_in_browser_main_timestamp,
272 std::unique_ptr<EventMetrics> CreateScrollUpdateEventMetrics(
273 ui::ScrollInputType input_type,
275 ScrollUpdateEventMetrics::ScrollUpdateType scroll_update_type) {
276 const base::TimeTicks event_time = AdvanceNowByMs(10);
277 const base::TimeTicks arrived_in_browser_main_timestamp = AdvanceNowByMs(3);
279 return SetupEventMetrics(ScrollUpdateEventMetrics::CreateForTesting(
280 ui::ET_GESTURE_SCROLL_UPDATE, input_type, is_inertial,
281 scroll_update_type, /*delta=*/10.0f, event_time,
282 arrived_in_browser_main_timestamp, &test_tick_clock_));
285 std::unique_ptr<EventMetrics> CreatePinchEventMetrics(
287 ui::ScrollInputType input_type) {
288 const base::TimeTicks event_time = AdvanceNowByMs(10);
290 return SetupEventMetrics(PinchEventMetrics::CreateForTesting(
291 type, input_type, event_time, &test_tick_clock_));
294 std::vector<base::TimeTicks> GetEventTimestamps(
295 const EventMetrics::List& events_metrics) {
296 std::vector<base::TimeTicks> event_times;
297 event_times.reserve(events_metrics.size());
298 std::transform(events_metrics.cbegin(), events_metrics.cend(),
299 std::back_inserter(event_times),
300 [](const auto& event_metrics) {
301 return event_metrics->GetDispatchStageTimestamp(
302 EventMetrics::DispatchStage::kGenerated);
308 // This should be defined before |reporting_controller_| so it is created
309 // before and destroyed after that.
310 base::SimpleTestTickClock test_tick_clock_;
312 TestCompositorFrameReportingController reporting_controller_;
313 viz::BeginFrameArgs args_;
314 viz::BeginFrameId current_id_;
315 viz::BeginFrameId last_activated_id_;
316 base::TimeTicks begin_impl_time_;
317 base::TimeTicks begin_main_time_;
318 base::TimeTicks begin_main_start_time_;
319 base::TimeTicks begin_commit_time_;
320 base::TimeTicks end_commit_time_;
321 base::TimeTicks begin_activation_time_;
322 base::TimeTicks end_activation_time_;
323 base::TimeTicks submit_time_;
324 viz::FrameTokenGenerator current_token_;
325 DroppedFrameCounter dropped_counter_;
326 TotalFrameCounter total_frame_counter_;
329 TEST_F(CompositorFrameReportingControllerTest, ActiveReporterCounts) {
330 // Check that there are no leaks with the CompositorFrameReporter
331 // objects no matter what the sequence of scheduled actions is
332 // Note that due to DCHECKs in WillCommit(), WillActivate(), etc., it
333 // is impossible to have 2 reporters both in BMF or Commit
336 // - 2 Reporters at Activate phase
337 // - 2 back-to-back BeginImplFrames
338 // - 4 Simultaneous Reporters
340 viz::BeginFrameId current_id_1(1, 1);
341 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
343 viz::BeginFrameId current_id_2(1, 2);
344 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
346 viz::BeginFrameId current_id_3(1, 3);
347 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
350 reporting_controller_.WillBeginImplFrame(args_1);
351 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
352 reporting_controller_.OnFinishImplFrame(args_1.frame_id);
353 reporting_controller_.DidNotProduceFrame(args_1.frame_id,
354 FrameSkippedReason::kNoDamage);
357 // Should replace previous reporter.
358 reporting_controller_.WillBeginImplFrame(args_2);
359 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
360 reporting_controller_.OnFinishImplFrame(args_2.frame_id);
361 reporting_controller_.DidNotProduceFrame(args_2.frame_id,
362 FrameSkippedReason::kNoDamage);
365 // Should add new reporter.
366 reporting_controller_.WillBeginMainFrame(args_2);
367 reporting_controller_.WillBeginImplFrame(args_3);
368 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
370 // BF -> BMF -> BF -> Commit
372 reporting_controller_.NotifyReadyToCommit(nullptr);
373 reporting_controller_.WillCommit();
374 reporting_controller_.DidCommit();
375 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
377 // BF -> BMF -> BF -> Commit -> BMF -> Activate -> Commit -> Activation
378 // Having two reporters at Activate phase should delete the older one.
379 reporting_controller_.WillBeginMainFrame(args_3);
380 reporting_controller_.WillActivate();
381 reporting_controller_.DidActivate();
383 // There is a reporters tracking frame_3 in BeginMain state and one reporter
384 // for frame_2 in activate state.
385 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
387 reporting_controller_.NotifyReadyToCommit(nullptr);
388 reporting_controller_.WillCommit();
389 reporting_controller_.DidCommit();
390 reporting_controller_.WillActivate();
391 reporting_controller_.DidActivate();
392 // Reporter in activate state for frame_2 is overwritten by the reporter for
394 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
396 last_activated_id_ = current_id_3;
397 reporting_controller_.DidSubmitCompositorFrame(
398 0, AdvanceNowByMs(10), current_id_3, last_activated_id_, {},
399 /*has_missing_content=*/false);
400 EXPECT_EQ(0, reporting_controller_.ActiveReporters());
402 // Start a frame and take it all the way to the activate stage.
404 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
406 // Start another frame and let it progress up to the commit stage.
407 SimulateCommit(nullptr);
408 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
410 // Start the next frame, and let it progress up to the main-frame.
411 SimulateBeginMainFrame();
412 EXPECT_EQ(3, reporting_controller_.ActiveReporters());
414 // Start the next frame.
415 SimulateBeginImplFrame();
416 EXPECT_EQ(4, reporting_controller_.ActiveReporters());
418 reporting_controller_.OnFinishImplFrame(args_.frame_id);
419 reporting_controller_.DidNotProduceFrame(args_.frame_id,
420 FrameSkippedReason::kNoDamage);
422 // Any additional BeginImplFrame's would be ignored.
423 SimulateBeginImplFrame();
424 EXPECT_EQ(4, reporting_controller_.ActiveReporters());
427 TEST_F(CompositorFrameReportingControllerTest,
428 StopRequestingFramesCancelsInFlightFrames) {
429 base::HistogramTester histogram_tester;
431 // 2 reporters active.
433 SimulateCommit(nullptr);
435 reporting_controller_.OnStoppedRequestingBeginFrames();
436 reporting_controller_.ResetReporters();
437 histogram_tester.ExpectBucketCount(
438 "CompositorLatency.Type",
439 CompositorFrameReporter::FrameReportType::kDroppedFrame, 0);
442 TEST_F(CompositorFrameReportingControllerTest,
443 SubmittedFrameHistogramReporting) {
444 base::HistogramTester histogram_tester;
446 // 2 reporters active.
448 SimulateCommit(nullptr);
450 // Submitting and Presenting the next reporter which will be a normal frame.
451 SimulatePresentCompositorFrame();
453 histogram_tester.ExpectTotalCount(
454 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
455 histogram_tester.ExpectTotalCount(
456 "CompositorLatency.DroppedFrame.SendBeginMainFrameToCommit", 0);
457 histogram_tester.ExpectTotalCount("CompositorLatency.DroppedFrame.Commit", 0);
458 histogram_tester.ExpectTotalCount(
459 "CompositorLatency.DroppedFrame.EndCommitToActivation", 0);
460 histogram_tester.ExpectTotalCount("CompositorLatency.DroppedFrame.Activation",
462 histogram_tester.ExpectTotalCount(
463 "CompositorLatency.DroppedFrame.EndActivateToSubmitCompositorFrame", 0);
464 histogram_tester.ExpectTotalCount(
465 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
466 histogram_tester.ExpectTotalCount(
467 "CompositorLatency.SendBeginMainFrameToCommit", 1);
468 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
469 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
471 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
472 histogram_tester.ExpectTotalCount(
473 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
475 // Submitting the next reporter will be replaced as a result of a new commit.
476 // And this will be reported for all stage before activate as a missed frame.
477 SimulateCommit(nullptr);
478 // Non Missed frame histogram counts should not change.
479 histogram_tester.ExpectTotalCount(
480 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
481 histogram_tester.ExpectTotalCount(
482 "CompositorLatency.SendBeginMainFrameToCommit", 1);
483 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
484 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
486 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
487 histogram_tester.ExpectTotalCount(
488 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
490 // Other histograms should be reported updated.
491 histogram_tester.ExpectTotalCount(
492 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 1);
493 histogram_tester.ExpectTotalCount(
494 "CompositorLatency.DroppedFrame.SendBeginMainFrameToCommit", 1);
495 histogram_tester.ExpectTotalCount("CompositorLatency.DroppedFrame.Commit", 1);
496 histogram_tester.ExpectTotalCount(
497 "CompositorLatency.DroppedFrame.EndCommitToActivation", 1);
498 histogram_tester.ExpectTotalCount("CompositorLatency.DroppedFrame.Activation",
500 histogram_tester.ExpectTotalCount(
501 "CompositorLatency.DroppedFrame.EndActivateToSubmitCompositorFrame", 0);
504 TEST_F(CompositorFrameReportingControllerTest, MainFrameCausedNoDamage) {
505 base::HistogramTester histogram_tester;
506 viz::BeginFrameId current_id_1(1, 1);
507 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
509 viz::BeginFrameId current_id_2(1, 2);
510 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
512 viz::BeginFrameId current_id_3(1, 3);
513 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
515 reporting_controller_.WillBeginImplFrame(args_1);
516 reporting_controller_.WillBeginMainFrame(args_1);
517 reporting_controller_.BeginMainFrameAborted(
518 current_id_1, CommitEarlyOutReason::FINISHED_NO_UPDATES);
519 reporting_controller_.OnFinishImplFrame(current_id_1);
520 reporting_controller_.DidNotProduceFrame(current_id_1,
521 FrameSkippedReason::kNoDamage);
523 reporting_controller_.WillBeginImplFrame(args_2);
524 reporting_controller_.WillBeginMainFrame(args_2);
525 reporting_controller_.OnFinishImplFrame(current_id_2);
526 reporting_controller_.BeginMainFrameAborted(
527 current_id_2, CommitEarlyOutReason::FINISHED_NO_UPDATES);
528 reporting_controller_.DidNotProduceFrame(current_id_2,
529 FrameSkippedReason::kNoDamage);
531 reporting_controller_.WillBeginImplFrame(args_3);
532 reporting_controller_.WillBeginMainFrame(args_3);
534 histogram_tester.ExpectTotalCount(
535 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
536 histogram_tester.ExpectTotalCount(
537 "CompositorLatency.DroppedFrame.SendBeginMainFrameToCommit", 0);
540 TEST_F(CompositorFrameReportingControllerTest, DidNotProduceFrame) {
541 base::HistogramTester histogram_tester;
543 viz::BeginFrameId current_id_1(1, 1);
544 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
546 viz::BeginFrameId current_id_2(1, 2);
547 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
549 reporting_controller_.WillBeginImplFrame(args_1);
550 reporting_controller_.WillBeginMainFrame(args_1);
551 reporting_controller_.OnFinishImplFrame(current_id_1);
552 reporting_controller_.DidNotProduceFrame(current_id_1,
553 FrameSkippedReason::kNoDamage);
555 reporting_controller_.WillBeginImplFrame(args_2);
556 reporting_controller_.OnFinishImplFrame(current_id_2);
557 reporting_controller_.NotifyReadyToCommit(nullptr);
558 reporting_controller_.WillCommit();
559 reporting_controller_.DidCommit();
560 reporting_controller_.WillActivate();
561 reporting_controller_.DidActivate();
562 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
563 current_id_2, current_id_1, {},
564 /*has_missing_content=*/false);
565 viz::FrameTimingDetails details = {};
566 reporting_controller_.DidPresentCompositorFrame(1, details);
568 histogram_tester.ExpectTotalCount(
569 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
570 histogram_tester.ExpectTotalCount(
571 "CompositorLatency.DroppedFrame.SendBeginMainFrameToCommit", 0);
572 histogram_tester.ExpectTotalCount(
573 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 2);
574 histogram_tester.ExpectTotalCount(
575 "CompositorLatency.SendBeginMainFrameToCommit", 1);
576 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
577 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
579 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
580 histogram_tester.ExpectTotalCount(
581 "CompositorLatency.EndActivateToSubmitCompositorFrame", 2);
582 histogram_tester.ExpectTotalCount(
583 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
585 histogram_tester.ExpectTotalCount(
586 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 1);
587 histogram_tester.ExpectTotalCount(
588 "CompositorLatency.CompositorOnlyFrame."
589 "ImplFrameDoneToSubmitCompositorFrame",
591 histogram_tester.ExpectTotalCount(
592 "CompositorLatency.CompositorOnlyFrame."
593 "SubmitCompositorFrameToPresentationCompositorFrame",
597 TEST_F(CompositorFrameReportingControllerTest,
598 DidNotProduceFrameDueToWaitingOnMain) {
599 base::HistogramTester histogram_tester;
601 viz::BeginFrameId current_id_1(1, 1);
602 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
604 viz::BeginFrameId current_id_2(1, 2);
605 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
606 args_2.frame_time = args_1.frame_time + args_1.interval;
608 viz::BeginFrameId current_id_3(1, 3);
609 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
610 args_3.frame_time = args_2.frame_time + args_2.interval;
612 reporting_controller_.WillBeginImplFrame(args_1);
613 reporting_controller_.WillBeginMainFrame(args_1);
614 reporting_controller_.OnFinishImplFrame(current_id_1);
615 reporting_controller_.DidNotProduceFrame(current_id_1,
616 FrameSkippedReason::kWaitingOnMain);
618 reporting_controller_.WillBeginImplFrame(args_2);
619 reporting_controller_.OnFinishImplFrame(current_id_2);
620 reporting_controller_.DidNotProduceFrame(current_id_2,
621 FrameSkippedReason::kWaitingOnMain);
623 reporting_controller_.WillBeginImplFrame(args_3);
624 reporting_controller_.NotifyReadyToCommit(nullptr);
625 reporting_controller_.WillCommit();
626 reporting_controller_.DidCommit();
627 reporting_controller_.WillActivate();
628 reporting_controller_.DidActivate();
629 reporting_controller_.OnFinishImplFrame(current_id_3);
630 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
631 current_id_3, current_id_1, {},
632 /*has_missing_content=*/false);
633 viz::FrameTimingDetails details;
634 details.presentation_feedback = {args_3.frame_time + args_3.interval,
636 reporting_controller_.DidPresentCompositorFrame(1, details);
638 // Frames for |args_1| and |args_2| were dropped waiting on the main-thread.
639 histogram_tester.ExpectBucketCount(
640 "CompositorLatency.Type",
641 CompositorFrameReporter::FrameReportType::kDroppedFrame, 2);
643 // Frames for |args_1| and |args_3| were presented with |args_3|, and |args_1|
644 // missed its deadline.
645 histogram_tester.ExpectBucketCount(
646 "CompositorLatency.Type",
647 CompositorFrameReporter::FrameReportType::kNonDroppedFrame, 2);
648 histogram_tester.ExpectBucketCount(
649 "CompositorLatency.Type",
650 CompositorFrameReporter::FrameReportType::kMissedDeadlineFrame, 1);
651 histogram_tester.ExpectBucketCount(
652 "CompositorLatency.Type",
653 CompositorFrameReporter::FrameReportType::kCompositorOnlyFrame, 1);
656 TEST_F(CompositorFrameReportingControllerTest, MainFrameAborted) {
657 base::HistogramTester histogram_tester;
659 reporting_controller_.WillBeginImplFrame(args_);
660 reporting_controller_.WillBeginMainFrame(args_);
661 reporting_controller_.BeginMainFrameAborted(
662 current_id_, CommitEarlyOutReason::FINISHED_NO_UPDATES);
663 reporting_controller_.OnFinishImplFrame(current_id_);
664 reporting_controller_.DidSubmitCompositorFrame(
665 1, AdvanceNowByMs(10), current_id_, last_activated_id_, {},
666 /*has_missing_content=*/false);
668 viz::FrameTimingDetails details = {};
669 reporting_controller_.DidPresentCompositorFrame(1, details);
671 histogram_tester.ExpectTotalCount(
672 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
673 histogram_tester.ExpectTotalCount(
674 "CompositorLatency.SendBeginMainFrameToCommit", 1);
675 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 0);
676 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 0);
677 histogram_tester.ExpectTotalCount(
678 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
679 histogram_tester.ExpectTotalCount(
680 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
682 histogram_tester.ExpectTotalCount(
683 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 1);
684 histogram_tester.ExpectTotalCount(
685 "CompositorLatency.CompositorOnlyFrame."
686 "SendBeginMainFrameToBeginMainAbort",
688 histogram_tester.ExpectTotalCount(
689 "CompositorLatency.CompositorOnlyFrame."
690 "ImplFrameDoneToSubmitCompositorFrame",
692 histogram_tester.ExpectTotalCount(
693 "CompositorLatency.CompositorOnlyFrame."
694 "SubmitCompositorFrameToPresentationCompositorFrame",
698 TEST_F(CompositorFrameReportingControllerTest, MainFrameAborted2) {
699 base::HistogramTester histogram_tester;
700 viz::BeginFrameId current_id_1(1, 1);
701 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
703 viz::BeginFrameId current_id_2(1, 2);
704 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
706 viz::BeginFrameId current_id_3(1, 3);
707 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
709 reporting_controller_.WillBeginImplFrame(args_1);
710 reporting_controller_.OnFinishImplFrame(current_id_1);
711 reporting_controller_.WillBeginMainFrame(args_1);
712 reporting_controller_.NotifyReadyToCommit(nullptr);
713 reporting_controller_.WillCommit();
714 reporting_controller_.DidCommit();
715 reporting_controller_.WillActivate();
716 reporting_controller_.DidActivate();
717 reporting_controller_.WillBeginImplFrame(args_2);
718 reporting_controller_.WillBeginMainFrame(args_2);
719 reporting_controller_.OnFinishImplFrame(current_id_2);
720 reporting_controller_.BeginMainFrameAborted(
721 current_id_2, CommitEarlyOutReason::FINISHED_NO_UPDATES);
722 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
723 current_id_2, current_id_1, {},
724 /*has_missing_content=*/false);
725 viz::FrameTimingDetails details = {};
726 reporting_controller_.DidPresentCompositorFrame(1, details);
727 histogram_tester.ExpectTotalCount(
728 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
729 histogram_tester.ExpectTotalCount(
730 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 2);
731 histogram_tester.ExpectTotalCount(
732 "CompositorLatency.SendBeginMainFrameToCommit", 2);
733 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
734 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
736 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
737 histogram_tester.ExpectTotalCount(
738 "CompositorLatency.EndActivateToSubmitCompositorFrame", 2);
739 histogram_tester.ExpectTotalCount(
740 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
742 reporting_controller_.DidSubmitCompositorFrame(2, AdvanceNowByMs(10),
743 current_id_2, current_id_1, {},
744 /*has_missing_content=*/false);
745 reporting_controller_.DidPresentCompositorFrame(2, details);
746 histogram_tester.ExpectTotalCount(
747 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
748 histogram_tester.ExpectTotalCount(
749 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 2);
750 histogram_tester.ExpectTotalCount(
751 "CompositorLatency.SendBeginMainFrameToCommit", 2);
752 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
753 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
755 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
756 histogram_tester.ExpectTotalCount(
757 "CompositorLatency.EndActivateToSubmitCompositorFrame", 2);
758 histogram_tester.ExpectTotalCount(
759 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
761 reporting_controller_.WillBeginImplFrame(args_3);
762 reporting_controller_.OnFinishImplFrame(current_id_3);
763 reporting_controller_.DidSubmitCompositorFrame(3, AdvanceNowByMs(10),
764 current_id_3, current_id_1, {},
765 /*has_missing_content=*/false);
766 reporting_controller_.DidPresentCompositorFrame(3, details);
767 histogram_tester.ExpectTotalCount(
768 "CompositorLatency.DroppedFrame.BeginImplFrameToSendBeginMainFrame", 0);
769 histogram_tester.ExpectTotalCount(
770 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 3);
771 histogram_tester.ExpectTotalCount(
772 "CompositorLatency.SendBeginMainFrameToCommit", 2);
773 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
774 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
776 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
777 histogram_tester.ExpectTotalCount(
778 "CompositorLatency.EndActivateToSubmitCompositorFrame", 3);
779 histogram_tester.ExpectTotalCount(
780 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
784 TEST_F(CompositorFrameReportingControllerTest, LongMainFrame) {
785 base::HistogramTester histogram_tester;
786 viz::BeginFrameId current_id_1(1, 1);
787 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
789 viz::BeginFrameId current_id_2(1, 2);
790 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
792 viz::BeginFrameId current_id_3(1, 3);
793 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
795 viz::FrameTimingDetails details = {};
796 reporting_controller_.WillBeginImplFrame(args_1);
797 reporting_controller_.OnFinishImplFrame(current_id_1);
798 reporting_controller_.WillBeginMainFrame(args_1);
799 reporting_controller_.NotifyReadyToCommit(nullptr);
800 reporting_controller_.WillCommit();
801 reporting_controller_.DidCommit();
802 reporting_controller_.WillActivate();
803 reporting_controller_.DidActivate();
804 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
805 current_id_1, current_id_1, {},
806 /*has_missing_content=*/false);
807 reporting_controller_.DidPresentCompositorFrame(1, details);
809 histogram_tester.ExpectTotalCount(
810 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
811 histogram_tester.ExpectTotalCount(
812 "CompositorLatency.SendBeginMainFrameToCommit", 1);
813 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
814 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
816 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
817 histogram_tester.ExpectTotalCount(
818 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
819 histogram_tester.ExpectTotalCount(
820 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
823 // Second frame will not have the main frame update ready and will only submit
825 reporting_controller_.WillBeginImplFrame(args_2);
826 reporting_controller_.WillBeginMainFrame(args_2);
827 reporting_controller_.OnFinishImplFrame(current_id_2);
828 reporting_controller_.DidSubmitCompositorFrame(2, AdvanceNowByMs(10),
829 current_id_2, current_id_1, {},
830 /*has_missing_content=*/false);
831 reporting_controller_.DidPresentCompositorFrame(2, details);
833 // The reporting for the second frame is delayed until the main-thread
835 histogram_tester.ExpectTotalCount(
836 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
837 histogram_tester.ExpectTotalCount(
838 "CompositorLatency.SendBeginMainFrameToCommit", 1);
839 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
840 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
842 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
843 histogram_tester.ExpectTotalCount(
844 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
845 histogram_tester.ExpectTotalCount(
846 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
848 histogram_tester.ExpectTotalCount(
849 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 0);
850 histogram_tester.ExpectTotalCount(
851 "CompositorLatency.CompositorOnlyFrame."
852 "SendBeginMainFrameToBeginMainAbort",
854 histogram_tester.ExpectTotalCount(
855 "CompositorLatency.CompositorOnlyFrame."
856 "ImplFrameDoneToSubmitCompositorFrame",
858 histogram_tester.ExpectTotalCount(
859 "CompositorLatency.CompositorOnlyFrame."
860 "SubmitCompositorFrameToPresentationCompositorFrame",
863 reporting_controller_.WillBeginImplFrame(args_3);
864 reporting_controller_.OnFinishImplFrame(current_id_3);
865 reporting_controller_.NotifyReadyToCommit(nullptr);
866 reporting_controller_.WillCommit();
867 reporting_controller_.DidCommit();
868 reporting_controller_.WillActivate();
869 reporting_controller_.DidActivate();
870 reporting_controller_.DidSubmitCompositorFrame(3, AdvanceNowByMs(10),
871 current_id_3, current_id_2, {},
872 /*has_missing_content=*/false);
873 reporting_controller_.DidPresentCompositorFrame(3, details);
875 // The main-thread responded, so the metrics for |args_2| should now be
877 histogram_tester.ExpectTotalCount(
878 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 4);
879 histogram_tester.ExpectTotalCount(
880 "CompositorLatency.SendBeginMainFrameToCommit", 2);
881 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 2);
882 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
884 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 2);
885 histogram_tester.ExpectTotalCount(
886 "CompositorLatency.EndActivateToSubmitCompositorFrame", 4);
887 histogram_tester.ExpectTotalCount(
888 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
890 histogram_tester.ExpectTotalCount(
891 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 2);
892 histogram_tester.ExpectTotalCount(
893 "CompositorLatency.CompositorOnlyFrame."
894 "SendBeginMainFrameToBeginMainAbort",
896 histogram_tester.ExpectTotalCount(
897 "CompositorLatency.CompositorOnlyFrame."
898 "ImplFrameDoneToSubmitCompositorFrame",
900 histogram_tester.ExpectTotalCount(
901 "CompositorLatency.CompositorOnlyFrame."
902 "SubmitCompositorFrameToPresentationCompositorFrame",
906 TEST_F(CompositorFrameReportingControllerTest, LongMainFrame2) {
907 base::HistogramTester histogram_tester;
908 viz::BeginFrameId current_id_1(1, 1);
909 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
911 viz::BeginFrameId current_id_2(1, 2);
912 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
914 viz::FrameTimingDetails details = {};
915 reporting_controller_.WillBeginImplFrame(args_1);
916 reporting_controller_.OnFinishImplFrame(current_id_1);
917 reporting_controller_.WillBeginMainFrame(args_1);
918 reporting_controller_.NotifyReadyToCommit(nullptr);
919 reporting_controller_.WillCommit();
920 reporting_controller_.DidCommit();
921 reporting_controller_.WillActivate();
922 reporting_controller_.DidActivate();
923 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
924 current_id_1, current_id_1, {},
925 /*has_missing_content=*/false);
926 reporting_controller_.DidPresentCompositorFrame(1, details);
928 histogram_tester.ExpectTotalCount(
929 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
930 histogram_tester.ExpectTotalCount(
931 "CompositorLatency.SendBeginMainFrameToCommit", 1);
932 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
933 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
935 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
936 histogram_tester.ExpectTotalCount(
937 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
938 histogram_tester.ExpectTotalCount(
939 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
942 // The reporting for the second frame is delayed until activation happens.
943 reporting_controller_.WillBeginImplFrame(args_2);
944 reporting_controller_.WillBeginMainFrame(args_2);
945 reporting_controller_.NotifyReadyToCommit(nullptr);
946 reporting_controller_.WillCommit();
947 reporting_controller_.DidCommit();
948 reporting_controller_.OnFinishImplFrame(current_id_2);
949 reporting_controller_.DidSubmitCompositorFrame(2, AdvanceNowByMs(10),
950 current_id_2, current_id_1, {},
951 /*has_missing_content=*/false);
952 reporting_controller_.DidPresentCompositorFrame(2, details);
954 histogram_tester.ExpectTotalCount(
955 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
956 histogram_tester.ExpectTotalCount(
957 "CompositorLatency.SendBeginMainFrameToCommit", 1);
958 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
959 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
961 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
962 histogram_tester.ExpectTotalCount(
963 "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
964 histogram_tester.ExpectTotalCount(
965 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
967 histogram_tester.ExpectTotalCount(
968 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 0);
969 histogram_tester.ExpectTotalCount(
970 "CompositorLatency.CompositorOnlyFrame."
971 "SendBeginMainFrameToBeginMainAbort",
973 histogram_tester.ExpectTotalCount(
974 "CompositorLatency.CompositorOnlyFrame."
975 "ImplFrameDoneToSubmitCompositorFrame",
977 histogram_tester.ExpectTotalCount(
978 "CompositorLatency.CompositorOnlyFrame."
979 "SubmitCompositorFrameToPresentationCompositorFrame",
982 viz::BeginFrameId current_id_3(1, 3);
983 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
985 // The metrics are reported for |args_2| after activation finally happens and
986 // a new frame is submitted.
987 reporting_controller_.WillActivate();
988 reporting_controller_.DidActivate();
989 reporting_controller_.WillBeginImplFrame(args_3);
990 reporting_controller_.OnFinishImplFrame(current_id_3);
991 reporting_controller_.DidSubmitCompositorFrame(3, AdvanceNowByMs(10),
992 current_id_3, current_id_2, {},
993 /*has_missing_content=*/false);
994 reporting_controller_.DidPresentCompositorFrame(3, details);
995 histogram_tester.ExpectTotalCount(
996 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 4);
997 histogram_tester.ExpectTotalCount(
998 "CompositorLatency.SendBeginMainFrameToCommit", 2);
999 histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 2);
1000 histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
1002 histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 2);
1003 histogram_tester.ExpectTotalCount(
1004 "CompositorLatency.EndActivateToSubmitCompositorFrame", 4);
1005 histogram_tester.ExpectTotalCount(
1006 "CompositorLatency.SubmitCompositorFrameToPresentationCompositorFrame",
1008 histogram_tester.ExpectTotalCount(
1009 "CompositorLatency.CompositorOnlyFrame.BeginImplFrameToFinishImpl", 2);
1010 histogram_tester.ExpectTotalCount(
1011 "CompositorLatency.CompositorOnlyFrame."
1012 "SendBeginMainFrameToBeginMainAbort",
1014 histogram_tester.ExpectTotalCount(
1015 "CompositorLatency.CompositorOnlyFrame."
1016 "ImplFrameDoneToSubmitCompositorFrame",
1018 histogram_tester.ExpectTotalCount(
1019 "CompositorLatency.CompositorOnlyFrame."
1020 "SubmitCompositorFrameToPresentationCompositorFrame",
1024 TEST_F(CompositorFrameReportingControllerTest, BlinkBreakdown) {
1025 base::HistogramTester histogram_tester;
1027 std::unique_ptr<BeginMainFrameMetrics> blink_breakdown =
1028 BuildBlinkBreakdown();
1030 SimulateCommit(std::move(blink_breakdown));
1031 SimulatePresentCompositorFrame();
1033 histogram_tester.ExpectTotalCount(
1034 "CompositorLatency.SendBeginMainFrameToCommit", 1);
1035 histogram_tester.ExpectUniqueSample(
1036 "CompositorLatency.SendBeginMainFrameToCommit.HandleInputEvents",
1037 base::Microseconds(10).InMilliseconds(), 1);
1038 histogram_tester.ExpectUniqueSample(
1039 "CompositorLatency.SendBeginMainFrameToCommit.Animate",
1040 base::Microseconds(9).InMilliseconds(), 1);
1041 histogram_tester.ExpectUniqueSample(
1042 "CompositorLatency.SendBeginMainFrameToCommit.StyleUpdate",
1043 base::Microseconds(8).InMilliseconds(), 1);
1044 histogram_tester.ExpectUniqueSample(
1045 "CompositorLatency.SendBeginMainFrameToCommit.LayoutUpdate",
1046 base::Microseconds(7).InMilliseconds(), 1);
1047 histogram_tester.ExpectUniqueSample(
1048 "CompositorLatency.SendBeginMainFrameToCommit.CompositingInputs",
1049 base::Microseconds(6).InMilliseconds(), 1);
1050 histogram_tester.ExpectUniqueSample(
1051 "CompositorLatency.SendBeginMainFrameToCommit.Prepaint",
1052 base::Microseconds(5).InMilliseconds(), 1);
1053 histogram_tester.ExpectUniqueSample(
1054 "CompositorLatency.SendBeginMainFrameToCommit.Paint",
1055 base::Microseconds(3).InMilliseconds(), 1);
1056 histogram_tester.ExpectUniqueSample(
1057 "CompositorLatency.SendBeginMainFrameToCommit.CompositeCommit",
1058 base::Microseconds(2).InMilliseconds(), 1);
1059 histogram_tester.ExpectUniqueSample(
1060 "CompositorLatency.SendBeginMainFrameToCommit.UpdateLayers",
1061 base::Microseconds(1).InMilliseconds(), 1);
1062 histogram_tester.ExpectTotalCount(
1063 "CompositorLatency.SendBeginMainFrameToCommit.BeginMainSentToStarted", 1);
1066 // If the presentation of the frame happens before deadline.
1067 TEST_F(CompositorFrameReportingControllerTest, ReportingMissedDeadlineFrame1) {
1068 base::HistogramTester histogram_tester;
1070 reporting_controller_.WillBeginImplFrame(args_);
1071 reporting_controller_.OnFinishImplFrame(current_id_);
1072 reporting_controller_.WillBeginMainFrame(args_);
1073 reporting_controller_.NotifyReadyToCommit(nullptr);
1074 reporting_controller_.WillCommit();
1075 reporting_controller_.DidCommit();
1076 reporting_controller_.WillActivate();
1077 reporting_controller_.DidActivate();
1078 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
1079 current_id_, current_id_, {},
1080 /*has_missing_content=*/false);
1081 viz::FrameTimingDetails details = {};
1082 details.presentation_feedback.timestamp =
1083 args_.frame_time + args_.interval * 1.5 - base::Microseconds(100);
1084 reporting_controller_.DidPresentCompositorFrame(1, details);
1086 histogram_tester.ExpectTotalCount(
1087 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
1088 histogram_tester.ExpectTotalCount("CompositorLatency.TotalLatency", 1);
1089 histogram_tester.ExpectTotalCount(
1090 "CompositorLatency.MissedDeadlineFrame."
1091 "BeginImplFrameToSendBeginMainFrame",
1093 histogram_tester.ExpectTotalCount(
1094 "CompositorLatency.MissedDeadlineFrame.TotalLatency", 0);
1096 // Non-dropped cases.
1097 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 0, 1);
1098 // Missed-deadline cases.
1099 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 1, 0);
1101 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 2, 0);
1103 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 3, 0);
1106 // If the presentation of the frame happens after deadline.
1107 TEST_F(CompositorFrameReportingControllerTest, ReportingMissedDeadlineFrame2) {
1108 base::HistogramTester histogram_tester;
1110 reporting_controller_.WillBeginImplFrame(args_);
1111 reporting_controller_.OnFinishImplFrame(current_id_);
1112 reporting_controller_.WillBeginMainFrame(args_);
1113 reporting_controller_.NotifyReadyToCommit(nullptr);
1114 reporting_controller_.WillCommit();
1115 reporting_controller_.DidCommit();
1116 reporting_controller_.WillActivate();
1117 reporting_controller_.DidActivate();
1118 reporting_controller_.DidSubmitCompositorFrame(1, AdvanceNowByMs(10),
1119 current_id_, current_id_, {},
1120 /*has_missing_content=*/false);
1121 viz::FrameTimingDetails details = {};
1122 details.presentation_feedback.timestamp =
1123 args_.frame_time + args_.interval * 1.5 + base::Microseconds(100);
1124 reporting_controller_.DidPresentCompositorFrame(1, details);
1126 histogram_tester.ExpectTotalCount(
1127 "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
1128 histogram_tester.ExpectTotalCount("CompositorLatency.TotalLatency", 1);
1129 histogram_tester.ExpectTotalCount(
1130 "CompositorLatency.MissedDeadlineFrame."
1131 "BeginImplFrameToSendBeginMainFrame",
1133 histogram_tester.ExpectTotalCount(
1134 "CompositorLatency.MissedDeadlineFrame.TotalLatency", 1);
1136 // Non-dropped cases.
1137 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 0, 1);
1138 // Missed-deadline cases.
1139 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 1, 1);
1141 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 2, 0);
1144 // If a compositor animation takes too long and throttles draw
1145 TEST_F(CompositorFrameReportingControllerTest, LongCompositorAnimation) {
1146 base::HistogramTester histogram_tester;
1148 SimulatePresentCompositorFrame();
1150 reporting_controller_.WillBeginImplFrame(args_);
1151 reporting_controller_.OnFinishImplFrame(current_id_);
1152 reporting_controller_.DidSubmitCompositorFrame(
1153 1, AdvanceNowByMs(10), current_id_, last_activated_id_, {},
1154 /*has_missing_content=*/false);
1155 viz::FrameTimingDetails details = {};
1156 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
1158 IncrementCurrentId();
1159 reporting_controller_.WillBeginImplFrame(args_);
1160 reporting_controller_.OnFinishImplFrame(current_id_);
1161 reporting_controller_.DidNotProduceFrame(args_.frame_id,
1162 FrameSkippedReason::kDrawThrottled);
1164 IncrementCurrentId();
1165 // Flushing the last no damage frame.
1166 reporting_controller_.WillBeginImplFrame(args_);
1167 reporting_controller_.OnFinishImplFrame(current_id_);
1169 EXPECT_EQ(3u, dropped_counter_.total_frames());
1170 EXPECT_EQ(1u, dropped_counter_.total_dropped());
1173 // Testing CompositorLatency.Type metrics
1174 TEST_F(CompositorFrameReportingControllerTest, ReportingLatencyType) {
1175 base::HistogramTester histogram_tester;
1177 SimulatePresentCompositorFrame();
1178 reporting_controller_.AddActiveTracker(
1179 FrameSequenceTrackerType::kCompositorAnimation);
1180 SimulatePresentCompositorFrame();
1181 reporting_controller_.AddActiveTracker(
1182 FrameSequenceTrackerType::kWheelScroll);
1183 SimulatePresentCompositorFrame();
1184 reporting_controller_.RemoveActiveTracker(
1185 FrameSequenceTrackerType::kCompositorAnimation);
1186 SimulatePresentCompositorFrame();
1187 reporting_controller_.RemoveActiveTracker(
1188 FrameSequenceTrackerType::kWheelScroll);
1189 SimulatePresentCompositorFrame();
1191 // All frames are presented so only test on-dropped cases.
1192 histogram_tester.ExpectBucketCount("CompositorLatency.Type", 0, 5);
1193 histogram_tester.ExpectBucketCount(
1194 "CompositorLatency.Type.CompositorAnimation", 0, 2);
1195 histogram_tester.ExpectBucketCount("CompositorLatency.Type.WheelScroll", 0,
1197 histogram_tester.ExpectBucketCount("CompositorLatency.Type.AnyInteraction", 0,
1199 histogram_tester.ExpectBucketCount("CompositorLatency.Type.NoInteraction", 0,
1203 // Tests that EventLatency total latency histograms are reported properly when a
1204 // frame is presented to the user.
1205 TEST_F(CompositorFrameReportingControllerTest,
1206 EventLatencyTotalForPresentedFrameReported) {
1207 base::HistogramTester histogram_tester;
1209 std::unique_ptr<EventMetrics> event_metrics_ptrs[] = {
1210 CreateEventMetrics(ui::ET_TOUCH_PRESSED),
1211 CreateEventMetrics(ui::ET_TOUCH_MOVED),
1212 CreateEventMetrics(ui::ET_TOUCH_MOVED),
1214 EXPECT_THAT(event_metrics_ptrs, Each(NotNull()));
1215 EventMetrics::List events_metrics(
1216 std::make_move_iterator(std::begin(event_metrics_ptrs)),
1217 std::make_move_iterator(std::end(event_metrics_ptrs)));
1218 std::vector<base::TimeTicks> event_times = GetEventTimestamps(events_metrics);
1220 // Submit a compositor frame and notify CompositorFrameReporter of the events
1221 // affecting the frame.
1222 SimulateSubmitCompositorFrame({std::move(events_metrics), {}});
1224 // Present the submitted compositor frame to the user.
1225 const base::TimeTicks presentation_time = AdvanceNowByMs(10);
1226 viz::FrameTimingDetails details;
1227 details.presentation_feedback.timestamp = presentation_time;
1228 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
1230 // Verify that EventLatency histograms are recorded.
1233 const base::HistogramBase::Count count;
1234 } expected_counts[] = {
1235 {"EventLatency.TouchPressed.TotalLatency", 1},
1236 {"EventLatency.TouchMoved.TotalLatency", 2},
1237 {"EventLatency.TotalLatency", 3},
1239 for (const auto& expected_count : expected_counts) {
1240 histogram_tester.ExpectTotalCount(expected_count.name,
1241 expected_count.count);
1246 const base::HistogramBase::Sample latency_ms;
1247 } expected_latencies[] = {
1248 {"EventLatency.TouchPressed.TotalLatency",
1249 static_cast<base::HistogramBase::Sample>(
1250 (presentation_time - event_times[0]).InMicroseconds())},
1251 {"EventLatency.TouchMoved.TotalLatency",
1252 static_cast<base::HistogramBase::Sample>(
1253 (presentation_time - event_times[1]).InMicroseconds())},
1254 {"EventLatency.TouchMoved.TotalLatency",
1255 static_cast<base::HistogramBase::Sample>(
1256 (presentation_time - event_times[2]).InMicroseconds())},
1257 {"EventLatency.TotalLatency",
1258 static_cast<base::HistogramBase::Sample>(
1259 (presentation_time - event_times[0]).InMicroseconds())},
1260 {"EventLatency.TotalLatency",
1261 static_cast<base::HistogramBase::Sample>(
1262 (presentation_time - event_times[1]).InMicroseconds())},
1263 {"EventLatency.TotalLatency",
1264 static_cast<base::HistogramBase::Sample>(
1265 (presentation_time - event_times[2]).InMicroseconds())},
1267 for (const auto& expected_latency : expected_latencies) {
1268 histogram_tester.ExpectBucketCount(expected_latency.name,
1269 expected_latency.latency_ms, 1);
1273 // Tests that EventLatency total latency histograms are reported properly for
1274 // scroll events when a frame is presented to the user.
1275 TEST_F(CompositorFrameReportingControllerTest,
1276 EventLatencyScrollTotalForPresentedFrameReported) {
1277 base::HistogramTester histogram_tester;
1279 const bool kScrollIsInertial = true;
1280 const bool kScrollIsNotInertial = false;
1281 std::unique_ptr<EventMetrics> event_metrics_ptrs[] = {
1282 CreateScrollBeginEventMetrics(ui::ScrollInputType::kWheel),
1283 CreateScrollUpdateEventMetrics(
1284 ui::ScrollInputType::kWheel, kScrollIsNotInertial,
1285 ScrollUpdateEventMetrics::ScrollUpdateType::kStarted),
1286 CreateScrollUpdateEventMetrics(
1287 ui::ScrollInputType::kWheel, kScrollIsNotInertial,
1288 ScrollUpdateEventMetrics::ScrollUpdateType::kContinued),
1289 CreateScrollUpdateEventMetrics(
1290 ui::ScrollInputType::kWheel, kScrollIsInertial,
1291 ScrollUpdateEventMetrics::ScrollUpdateType::kContinued),
1292 CreateScrollBeginEventMetrics(ui::ScrollInputType::kTouchscreen),
1293 CreateScrollUpdateEventMetrics(
1294 ui::ScrollInputType::kTouchscreen, kScrollIsNotInertial,
1295 ScrollUpdateEventMetrics::ScrollUpdateType::kStarted),
1296 CreateScrollUpdateEventMetrics(
1297 ui::ScrollInputType::kTouchscreen, kScrollIsNotInertial,
1298 ScrollUpdateEventMetrics::ScrollUpdateType::kContinued),
1299 CreateScrollUpdateEventMetrics(
1300 ui::ScrollInputType::kTouchscreen, kScrollIsInertial,
1301 ScrollUpdateEventMetrics::ScrollUpdateType::kContinued),
1303 EXPECT_THAT(event_metrics_ptrs, Each(NotNull()));
1304 EventMetrics::List events_metrics(
1305 std::make_move_iterator(std::begin(event_metrics_ptrs)),
1306 std::make_move_iterator(std::end(event_metrics_ptrs)));
1307 std::vector<base::TimeTicks> event_times = GetEventTimestamps(events_metrics);
1309 // Submit a compositor frame and notify CompositorFrameReporter of the events
1310 // affecting the frame.
1311 SimulateSubmitCompositorFrame({std::move(events_metrics), {}});
1313 // Present the submitted compositor frame to the user.
1314 viz::FrameTimingDetails details;
1315 details.received_compositor_frame_timestamp = AdvanceNowByMs(10);
1316 details.draw_start_timestamp = AdvanceNowByMs(10);
1317 details.swap_timings.swap_start = AdvanceNowByMs(10);
1318 details.swap_timings.swap_end = AdvanceNowByMs(10);
1319 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
1320 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
1322 // Verify that EventLatency histograms are recorded.
1325 const base::HistogramBase::Count count;
1326 } expected_counts[] = {
1327 {"EventLatency.GestureScrollBegin.Wheel.TotalLatency", 1},
1328 {"EventLatency.FirstGestureScrollUpdate.Wheel.TotalLatency", 1},
1329 {"EventLatency.GestureScrollUpdate.Wheel.TotalLatency", 1},
1330 {"EventLatency.InertialGestureScrollUpdate.Wheel.TotalLatency", 1},
1331 {"EventLatency.GestureScrollBegin.Touchscreen.TotalLatency", 1},
1332 {"EventLatency.FirstGestureScrollUpdate.Touchscreen.TotalLatency", 1},
1333 {"EventLatency.GestureScrollUpdate.Touchscreen.TotalLatency", 1},
1334 {"EventLatency.InertialGestureScrollUpdate.Touchscreen.TotalLatency", 1},
1335 {"EventLatency.GestureScrollBegin.TotalLatency", 2},
1336 {"EventLatency.FirstGestureScrollUpdate.TotalLatency", 2},
1337 {"EventLatency.GestureScrollUpdate.TotalLatency", 2},
1338 {"EventLatency.InertialGestureScrollUpdate.TotalLatency", 2},
1339 {"EventLatency.TotalLatency", 8},
1341 for (const auto& expected_count : expected_counts) {
1342 histogram_tester.ExpectTotalCount(expected_count.name,
1343 expected_count.count);
1346 const base::TimeTicks presentation_time =
1347 details.presentation_feedback.timestamp;
1350 const base::HistogramBase::Sample latency_ms;
1351 } expected_latencies[] = {
1352 {"EventLatency.GestureScrollBegin.Wheel.TotalLatency",
1353 static_cast<base::HistogramBase::Sample>(
1354 (presentation_time - event_times[0]).InMicroseconds())},
1355 {"EventLatency.FirstGestureScrollUpdate.Wheel.TotalLatency",
1356 static_cast<base::HistogramBase::Sample>(
1357 (presentation_time - event_times[1]).InMicroseconds())},
1358 {"EventLatency.GestureScrollUpdate.Wheel.TotalLatency",
1359 static_cast<base::HistogramBase::Sample>(
1360 (presentation_time - event_times[2]).InMicroseconds())},
1361 {"EventLatency.InertialGestureScrollUpdate.Wheel.TotalLatency",
1362 static_cast<base::HistogramBase::Sample>(
1363 (presentation_time - event_times[3]).InMicroseconds())},
1364 {"EventLatency.GestureScrollBegin.Touchscreen.TotalLatency",
1365 static_cast<base::HistogramBase::Sample>(
1366 (presentation_time - event_times[4]).InMicroseconds())},
1367 {"EventLatency.FirstGestureScrollUpdate.Touchscreen.TotalLatency",
1368 static_cast<base::HistogramBase::Sample>(
1369 (presentation_time - event_times[5]).InMicroseconds())},
1370 {"EventLatency.GestureScrollUpdate.Touchscreen.TotalLatency",
1371 static_cast<base::HistogramBase::Sample>(
1372 (presentation_time - event_times[6]).InMicroseconds())},
1373 {"EventLatency.InertialGestureScrollUpdate.Touchscreen.TotalLatency",
1374 static_cast<base::HistogramBase::Sample>(
1375 (presentation_time - event_times[7]).InMicroseconds())},
1377 for (const auto& expected_latency : expected_latencies) {
1378 histogram_tester.ExpectBucketCount(expected_latency.name,
1379 expected_latency.latency_ms, 1);
1383 TEST_F(CompositorFrameReportingControllerTest,
1384 EventLatencyMainRepaintedScroll) {
1385 base::HistogramTester histogram_tester;
1387 // Set up two EventMetrics objects.
1388 std::unique_ptr<EventMetrics> metrics_1 = CreateScrollUpdateEventMetrics(
1389 ui::ScrollInputType::kWheel, /*is_inertial=*/false,
1390 ScrollUpdateEventMetrics::ScrollUpdateType::kStarted);
1391 metrics_1->set_requires_main_thread_update();
1392 base::TimeTicks start_time_1 = metrics_1->GetDispatchStageTimestamp(
1393 EventMetrics::DispatchStage::kGenerated);
1395 // The second EventMetrics does not have set_requires_main_thread_update().
1396 // (It's not very realistic for the same scroll gesture to produce two events
1397 // with differing values for this bit, but let's test both conditions here.)
1398 std::unique_ptr<EventMetrics> metrics_2 = CreateScrollUpdateEventMetrics(
1399 ui::ScrollInputType::kWheel, /*is_inertial=*/false,
1400 ScrollUpdateEventMetrics::ScrollUpdateType::kContinued);
1401 base::TimeTicks start_time_2 = metrics_2->GetDispatchStageTimestamp(
1402 EventMetrics::DispatchStage::kGenerated);
1404 // Simulate a frame getting stuck in the main thread.
1405 SimulateBeginImplFrame();
1406 SimulateBeginMainFrame();
1407 reporting_controller_.OnFinishImplFrame(current_id_);
1409 // Submit a partial update with our events from the compositor thread.
1410 EventMetrics::List metrics_list;
1411 metrics_list.push_back(std::move(metrics_1));
1412 metrics_list.push_back(std::move(metrics_2));
1413 reporting_controller_.DidSubmitCompositorFrame(
1414 *current_token_, AdvanceNowByMs(10), current_id_, {},
1415 {{}, std::move(metrics_list)},
1416 /*has_missing_content=*/false);
1418 // Present the partial update.
1419 viz::FrameTimingDetails details_1 = {};
1420 details_1.presentation_feedback.timestamp = AdvanceNowByMs(10);
1421 reporting_controller_.DidPresentCompositorFrame(*current_token_, details_1);
1423 // Let the main thread finish its work.
1424 SimulateCommit(nullptr);
1427 // Submit the final update.
1428 SimulateBeginImplFrame();
1429 reporting_controller_.OnFinishImplFrame(current_id_);
1430 SimulateSubmitCompositorFrame({});
1432 // Present the final update.
1433 viz::FrameTimingDetails details_2 = {};
1434 details_2.presentation_feedback.timestamp = AdvanceNowByMs(10);
1435 reporting_controller_.DidPresentCompositorFrame(*current_token_, details_2);
1437 // metrics_1 has requires_main_thread_update(), so its latency is based on the
1438 // final-update presentation (details_2).
1439 base::TimeDelta expected_latency_1 =
1440 details_2.presentation_feedback.timestamp - start_time_1;
1441 histogram_tester.ExpectBucketCount(
1442 "EventLatency.FirstGestureScrollUpdate.Wheel.TotalLatency",
1443 expected_latency_1.InMicroseconds(), 1);
1445 // metrics_2 did NOT have requires_main_thread_update(), so its latency is
1446 // based on the partial-update presentation (details_1).
1447 base::TimeDelta expected_latency_2 =
1448 details_1.presentation_feedback.timestamp - start_time_2;
1449 histogram_tester.ExpectBucketCount(
1450 "EventLatency.GestureScrollUpdate.Wheel.TotalLatency",
1451 expected_latency_2.InMicroseconds(), 1);
1454 // Tests that EventLatency total latency histograms are reported properly for
1455 // pinch events when a frame is presented to the user.
1456 TEST_F(CompositorFrameReportingControllerTest,
1457 EventLatencyPinchTotalForPresentedFrameReported) {
1458 base::HistogramTester histogram_tester;
1460 std::unique_ptr<EventMetrics> event_metrics_ptrs[] = {
1461 CreatePinchEventMetrics(ui::ET_GESTURE_PINCH_BEGIN,
1462 ui::ScrollInputType::kWheel),
1463 CreatePinchEventMetrics(ui::ET_GESTURE_PINCH_UPDATE,
1464 ui::ScrollInputType::kWheel),
1465 CreatePinchEventMetrics(ui::ET_GESTURE_PINCH_BEGIN,
1466 ui::ScrollInputType::kTouchscreen),
1467 CreatePinchEventMetrics(ui::ET_GESTURE_PINCH_UPDATE,
1468 ui::ScrollInputType::kTouchscreen),
1470 EXPECT_THAT(event_metrics_ptrs, Each(NotNull()));
1471 EventMetrics::List events_metrics(
1472 std::make_move_iterator(std::begin(event_metrics_ptrs)),
1473 std::make_move_iterator(std::end(event_metrics_ptrs)));
1474 std::vector<base::TimeTicks> event_times = GetEventTimestamps(events_metrics);
1476 // Submit a compositor frame and notify CompositorFrameReporter of the events
1477 // affecting the frame.
1478 SimulateSubmitCompositorFrame({std::move(events_metrics), {}});
1480 // Present the submitted compositor frame to the user.
1481 viz::FrameTimingDetails details;
1482 details.received_compositor_frame_timestamp = AdvanceNowByMs(10);
1483 details.draw_start_timestamp = AdvanceNowByMs(10);
1484 details.swap_timings.swap_start = AdvanceNowByMs(10);
1485 details.swap_timings.swap_end = AdvanceNowByMs(10);
1486 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
1487 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
1489 // Verify that EventLatency histograms are recorded.
1492 const base::HistogramBase::Count count;
1493 } expected_counts[] = {
1494 {"EventLatency.GesturePinchBegin.Touchpad.TotalLatency", 1},
1495 {"EventLatency.GesturePinchUpdate.Touchpad.TotalLatency", 1},
1496 {"EventLatency.GesturePinchBegin.Touchscreen.TotalLatency", 1},
1497 {"EventLatency.GesturePinchUpdate.Touchscreen.TotalLatency", 1},
1498 {"EventLatency.TotalLatency", 4},
1500 for (const auto& expected_count : expected_counts) {
1501 histogram_tester.ExpectTotalCount(expected_count.name,
1502 expected_count.count);
1505 const base::TimeTicks presentation_time =
1506 details.presentation_feedback.timestamp;
1509 const base::HistogramBase::Sample latency_ms;
1510 } expected_latencies[] = {
1511 {"EventLatency.GesturePinchBegin.Touchpad.TotalLatency",
1512 static_cast<base::HistogramBase::Sample>(
1513 (presentation_time - event_times[0]).InMicroseconds())},
1514 {"EventLatency.GesturePinchUpdate.Touchpad.TotalLatency",
1515 static_cast<base::HistogramBase::Sample>(
1516 (presentation_time - event_times[1]).InMicroseconds())},
1517 {"EventLatency.GesturePinchBegin.Touchscreen.TotalLatency",
1518 static_cast<base::HistogramBase::Sample>(
1519 (presentation_time - event_times[2]).InMicroseconds())},
1520 {"EventLatency.GesturePinchUpdate.Touchscreen.TotalLatency",
1521 static_cast<base::HistogramBase::Sample>(
1522 (presentation_time - event_times[3]).InMicroseconds())},
1524 for (const auto& expected_latency : expected_latencies) {
1525 histogram_tester.ExpectBucketCount(expected_latency.name,
1526 expected_latency.latency_ms, 1);
1530 // Tests that EventLatency histograms for events of a dropped frame are reported
1531 // in the first subsequent presented frame.
1532 TEST_F(CompositorFrameReportingControllerTest,
1533 EventLatencyForDidNotPresentFrameReportedOnNextPresent) {
1534 base::HistogramTester histogram_tester;
1536 std::unique_ptr<EventMetrics> event_metrics_ptrs[] = {
1537 CreateEventMetrics(ui::ET_TOUCH_PRESSED),
1538 CreateEventMetrics(ui::ET_TOUCH_MOVED),
1539 CreateEventMetrics(ui::ET_TOUCH_MOVED),
1541 EXPECT_THAT(event_metrics_ptrs, Each(NotNull()));
1542 EventMetrics::List events_metrics(
1543 std::make_move_iterator(std::begin(event_metrics_ptrs)),
1544 std::make_move_iterator(std::end(event_metrics_ptrs)));
1545 std::vector<base::TimeTicks> event_times = GetEventTimestamps(events_metrics);
1547 // Submit a compositor frame and notify CompositorFrameReporter of the events
1548 // affecting the frame.
1549 SimulateSubmitCompositorFrame({std::move(events_metrics), {}});
1551 // Submit another compositor frame.
1552 IncrementCurrentId();
1553 SimulateSubmitCompositorFrame({});
1555 // Present the second compositor frame to the user, dropping the first one.
1556 const base::TimeTicks presentation_time = AdvanceNowByMs(10);
1557 viz::FrameTimingDetails details;
1558 details.presentation_feedback.timestamp = presentation_time;
1559 reporting_controller_.DidPresentCompositorFrame(*current_token_, details);
1561 // Verify that EventLatency histograms for the first frame (dropped) are
1562 // recorded using the presentation time of the second frame (presented).
1565 const base::HistogramBase::Count count;
1566 } expected_counts[] = {
1567 {"EventLatency.TouchPressed.TotalLatency", 1},
1568 {"EventLatency.TouchMoved.TotalLatency", 2},
1569 {"EventLatency.TotalLatency", 3},
1571 for (const auto& expected_count : expected_counts) {
1572 histogram_tester.ExpectTotalCount(expected_count.name,
1573 expected_count.count);
1578 const base::HistogramBase::Sample latency_ms;
1579 } expected_latencies[] = {
1580 {"EventLatency.TouchPressed.TotalLatency",
1581 static_cast<base::HistogramBase::Sample>(
1582 (presentation_time - event_times[0]).InMicroseconds())},
1583 {"EventLatency.TouchMoved.TotalLatency",
1584 static_cast<base::HistogramBase::Sample>(
1585 (presentation_time - event_times[1]).InMicroseconds())},
1586 {"EventLatency.TouchMoved.TotalLatency",
1587 static_cast<base::HistogramBase::Sample>(
1588 (presentation_time - event_times[2]).InMicroseconds())},
1589 {"EventLatency.TotalLatency",
1590 static_cast<base::HistogramBase::Sample>(
1591 (presentation_time - event_times[0]).InMicroseconds())},
1592 {"EventLatency.TotalLatency",
1593 static_cast<base::HistogramBase::Sample>(
1594 (presentation_time - event_times[1]).InMicroseconds())},
1595 {"EventLatency.TotalLatency",
1596 static_cast<base::HistogramBase::Sample>(
1597 (presentation_time - event_times[2]).InMicroseconds())},
1599 for (const auto& expected_latency : expected_latencies) {
1600 histogram_tester.ExpectBucketCount(expected_latency.name,
1601 expected_latency.latency_ms, 1);
1605 TEST_F(CompositorFrameReportingControllerTest,
1606 NewMainUpdateIsNotPartialUpdate) {
1607 // Start a frame with main-thread update. Submit the frame (and present)
1608 // before the main-thread responds. This creates two reporters: R1C and R1M
1609 // (R1C for the submitted frame with updates from compositor-thread, and R1M
1610 // for the pending main-thread frame).
1611 SimulateBeginMainFrame();
1612 reporting_controller_.OnFinishImplFrame(current_id_);
1613 reporting_controller_.DidSubmitCompositorFrame(1u, AdvanceNowByMs(10),
1614 current_id_, {}, {},
1615 /*has_missing_content=*/false);
1616 viz::FrameTimingDetails details = {};
1617 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
1618 reporting_controller_.DidPresentCompositorFrame(1u, details);
1620 // The main-thread responds now, triggering a commit and activation.
1621 reporting_controller_.NotifyReadyToCommit(nullptr);
1622 reporting_controller_.WillCommit();
1623 reporting_controller_.DidCommit();
1624 reporting_controller_.WillActivate();
1625 reporting_controller_.DidActivate();
1627 const auto previous_id = current_id_;
1629 // Start a new frame with main-thread update. Submit the frame (and present)
1630 // before the main-thread responds. This also again creates two reporters: R2C
1632 SimulateBeginMainFrame();
1633 reporting_controller_.OnFinishImplFrame(current_id_);
1634 reporting_controller_.DidSubmitCompositorFrame(1u, AdvanceNowByMs(10),
1635 current_id_, previous_id, {},
1636 /*has_missing_content=*/false);
1637 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
1638 reporting_controller_.DidPresentCompositorFrame(1u, details);
1640 // In total, two frames have been completed: R1C, and R1M.
1641 // R2C has been presented, but it is blocked on R2M to know whether R2C
1642 // contains partial update, or complete updates. So it is kept alive.
1643 EXPECT_EQ(2u, dropped_counter_.total_frames());
1644 EXPECT_EQ(1u, dropped_counter_.total_partial());
1645 EXPECT_EQ(1u, reporting_controller_.GetBlockingReportersCount());
1646 EXPECT_EQ(1u, reporting_controller_.GetBlockedReportersCount());
1648 reporting_controller_.ResetReporters();
1649 reporting_controller_.SetDroppedFrameCounter(nullptr);
1652 // Verifies that when a dependent frame is submitted to Viz, but not presented
1653 // (hence dropped), should have its reporter immediately terminated and not
1654 // adopted by the decider reporter.
1655 TEST_F(CompositorFrameReportingControllerTest,
1656 DependentDroppedFrameTerminatesReporterImmediately) {
1657 // Start a frame with main-thread update and let it get stuck in main-thread.
1658 SimulateBeginMainFrame();
1659 reporting_controller_.OnFinishImplFrame(current_id_);
1661 // Start another frame that has impl-thread update and submit and present it
1662 // successfully. The reporter for this frame should become dependent of the
1663 // main reporter and adopted by it.
1664 SimulateBeginImplFrame();
1665 reporting_controller_.OnFinishImplFrame(current_id_);
1666 reporting_controller_.DidSubmitCompositorFrame(1u, AdvanceNowByMs(10),
1667 current_id_, {}, {},
1668 /*has_missing_content=*/false);
1670 viz::FrameTimingDetails details_1 = {};
1671 details_1.presentation_feedback.timestamp = AdvanceNowByMs(10);
1672 reporting_controller_.DidPresentCompositorFrame(1u, details_1);
1674 // There should be 1 blocking reporter, 1 blocked reporter, and 1 adopted
1676 EXPECT_EQ(1u, reporting_controller_.GetBlockingReportersCount());
1677 EXPECT_EQ(1u, reporting_controller_.GetBlockedReportersCount());
1678 EXPECT_EQ(1u, reporting_controller_.GetAdoptedReportersCount());
1680 // At this point no frame has been completed, yet.
1681 EXPECT_EQ(0u, dropped_counter_.total_frames());
1682 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1684 // Start yet another frame that has impl-thread update and submit it, but with
1685 // failed presentation. The reporter for this frame should become dependent of
1686 // the main reporter, but should terminated immediately upon presentation
1687 // failure, hence not adopted by the main reporter.
1688 SimulateBeginImplFrame();
1689 reporting_controller_.OnFinishImplFrame(current_id_);
1690 reporting_controller_.DidSubmitCompositorFrame(2u, AdvanceNowByMs(10),
1691 current_id_, {}, {},
1692 /*has_missing_content=*/false);
1694 viz::FrameTimingDetails details_2 = {};
1695 details_2.presentation_feedback.timestamp = AdvanceNowByMs(10);
1696 details_2.presentation_feedback.flags |= gfx::PresentationFeedback::kFailure;
1697 reporting_controller_.DidPresentCompositorFrame(2u, details_2);
1699 // There should be still 1 blocking reporter, but 2 blocked reporters. There
1700 // should also be only 1 adopted reporter as the new reporter should not be
1702 EXPECT_EQ(1u, reporting_controller_.GetBlockingReportersCount());
1703 EXPECT_EQ(2u, reporting_controller_.GetBlockedReportersCount());
1704 EXPECT_EQ(1u, reporting_controller_.GetAdoptedReportersCount());
1706 // At this point 1 frame has been completed and it's a dropped frame.
1707 EXPECT_EQ(1u, dropped_counter_.total_frames());
1708 EXPECT_EQ(1u, dropped_counter_.total_dropped());
1710 reporting_controller_.ResetReporters();
1711 reporting_controller_.SetDroppedFrameCounter(nullptr);
1714 TEST_F(CompositorFrameReportingControllerTest,
1715 SkippedFramesFromDisplayCompositorAreDropped) {
1716 // Submit and present two compositor frames.
1717 SimulatePresentCompositorFrame();
1718 EXPECT_EQ(1u, dropped_counter_.total_frames());
1719 EXPECT_EQ(0u, dropped_counter_.total_partial());
1720 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1722 SimulatePresentCompositorFrame();
1723 EXPECT_EQ(2u, dropped_counter_.total_frames());
1724 EXPECT_EQ(0u, dropped_counter_.total_partial());
1725 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1727 // Now skip over a few frames, and submit + present another frame.
1728 const uint32_t kSkipFrames = 5;
1729 for (uint32_t i = 0; i < kSkipFrames; ++i)
1730 IncrementCurrentId();
1731 SimulatePresentCompositorFrame();
1732 EXPECT_EQ(3u + kSkipFrames, dropped_counter_.total_frames());
1733 EXPECT_EQ(0u, dropped_counter_.total_partial());
1734 EXPECT_EQ(kSkipFrames, dropped_counter_.total_dropped());
1736 // Stop requesting frames, skip over a few frames, and submit + present
1737 // another frame. There should no new dropped frames.
1738 dropped_counter_.Reset();
1739 reporting_controller_.OnStoppedRequestingBeginFrames();
1740 for (uint32_t i = 0; i < kSkipFrames; ++i)
1741 IncrementCurrentId();
1742 SimulatePresentCompositorFrame();
1743 EXPECT_EQ(1u, dropped_counter_.total_frames());
1744 EXPECT_EQ(0u, dropped_counter_.total_partial());
1745 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1747 reporting_controller_.ResetReporters();
1748 reporting_controller_.SetDroppedFrameCounter(nullptr);
1751 TEST_F(CompositorFrameReportingControllerTest,
1752 SkippedFramesFromDisplayCompositorAreDroppedUpToLimit) {
1753 // Submit and present two compositor frames.
1754 SimulatePresentCompositorFrame();
1755 EXPECT_EQ(1u, dropped_counter_.total_frames());
1756 EXPECT_EQ(0u, dropped_counter_.total_partial());
1757 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1759 SimulatePresentCompositorFrame();
1760 EXPECT_EQ(2u, dropped_counter_.total_frames());
1761 EXPECT_EQ(0u, dropped_counter_.total_partial());
1762 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1764 // Now skip over a 101 frames (It should be ignored as it more than 100)
1765 // and submit + present another frame.
1766 const uint32_t kSkipFrames = 101;
1767 const uint32_t kSkipFramesActual = 0;
1768 for (uint32_t i = 0; i < kSkipFrames; ++i)
1769 IncrementCurrentId();
1770 SimulatePresentCompositorFrame();
1771 EXPECT_EQ(3u + kSkipFramesActual, dropped_counter_.total_frames());
1772 EXPECT_EQ(0u, dropped_counter_.total_partial());
1773 EXPECT_EQ(kSkipFramesActual, dropped_counter_.total_dropped());
1776 TEST_F(CompositorFrameReportingControllerTest,
1777 CompositorFrameBlockedOnMainFrameWithNoDamage) {
1778 viz::BeginFrameId current_id_1(1, 1);
1779 viz::BeginFrameArgs args_1 = SimulateBeginFrameArgs(current_id_1);
1781 viz::BeginFrameId current_id_2(1, 2);
1782 viz::BeginFrameArgs args_2 = SimulateBeginFrameArgs(current_id_2);
1784 viz::BeginFrameId current_id_3(1, 3);
1785 viz::BeginFrameArgs args_3 = SimulateBeginFrameArgs(current_id_3);
1787 viz::BeginFrameId current_id_4(1, 4);
1788 viz::BeginFrameArgs args_4 = SimulateBeginFrameArgs(current_id_4);
1790 reporting_controller_.WillBeginImplFrame(args_1);
1791 reporting_controller_.WillBeginMainFrame(args_1);
1792 reporting_controller_.OnFinishImplFrame(current_id_1);
1793 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1794 reporting_controller_.DidNotProduceFrame(args_1.frame_id,
1795 FrameSkippedReason::kWaitingOnMain);
1797 reporting_controller_.WillBeginImplFrame(args_2);
1798 reporting_controller_.OnFinishImplFrame(args_2.frame_id);
1799 reporting_controller_.DidNotProduceFrame(args_2.frame_id,
1800 FrameSkippedReason::kWaitingOnMain);
1802 reporting_controller_.WillBeginImplFrame(args_3);
1803 reporting_controller_.OnFinishImplFrame(args_3.frame_id);
1804 reporting_controller_.DidNotProduceFrame(args_3.frame_id,
1805 FrameSkippedReason::kWaitingOnMain);
1807 EXPECT_EQ(1u, reporting_controller_.GetBlockingReportersCount());
1808 EXPECT_EQ(3u, reporting_controller_.GetBlockedReportersCount());
1810 // All frames are waiting for the main frame
1811 EXPECT_EQ(0u, dropped_counter_.total_partial());
1812 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1813 EXPECT_EQ(0u, dropped_counter_.total_frames());
1815 reporting_controller_.BeginMainFrameAborted(
1816 args_1.frame_id, CommitEarlyOutReason::FINISHED_NO_UPDATES);
1817 reporting_controller_.DidNotProduceFrame(args_1.frame_id,
1818 FrameSkippedReason::kNoDamage);
1819 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1821 // New reporters replace older reporters
1822 reporting_controller_.WillBeginImplFrame(args_4);
1823 reporting_controller_.WillBeginMainFrame(args_4);
1825 EXPECT_EQ(4u, dropped_counter_.total_frames());
1826 EXPECT_EQ(0u, dropped_counter_.total_partial());
1827 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1830 TEST_F(CompositorFrameReportingControllerTest,
1831 SkippedFramesFromDisplayCompositorHaveSmoothThread) {
1832 auto thread_type_compositor = SmoothEffectDrivingThread::kCompositor;
1833 reporting_controller_.SetThreadAffectsSmoothness(thread_type_compositor,
1835 dropped_counter_.OnFcpReceived();
1837 // Submit and present two compositor frames.
1838 SimulatePresentCompositorFrame();
1839 EXPECT_EQ(1u, dropped_counter_.total_frames());
1840 EXPECT_EQ(0u, dropped_counter_.total_partial());
1841 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1843 SimulatePresentCompositorFrame();
1844 EXPECT_EQ(2u, dropped_counter_.total_frames());
1845 EXPECT_EQ(0u, dropped_counter_.total_partial());
1846 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1848 // Now skip over a few frames, and submit + present another frame.
1849 const uint32_t kSkipFrames_1 = 5;
1850 for (uint32_t i = 0; i < kSkipFrames_1; ++i)
1851 IncrementCurrentId();
1852 SimulatePresentCompositorFrame();
1853 EXPECT_EQ(3u + kSkipFrames_1, dropped_counter_.total_frames());
1854 EXPECT_EQ(0u, dropped_counter_.total_partial());
1855 EXPECT_EQ(kSkipFrames_1, dropped_counter_.total_dropped());
1856 EXPECT_EQ(kSkipFrames_1, dropped_counter_.total_smoothness_dropped());
1858 // Now skip over a few frames which are not affecting smoothness.
1859 reporting_controller_.SetThreadAffectsSmoothness(thread_type_compositor,
1861 const uint32_t kSkipFrames_2 = 7;
1862 for (uint32_t i = 0; i < kSkipFrames_2; ++i)
1863 IncrementCurrentId();
1864 SimulatePresentCompositorFrame(); // Present another frame.
1865 EXPECT_EQ(4u + kSkipFrames_1 + kSkipFrames_2,
1866 dropped_counter_.total_frames());
1867 EXPECT_EQ(0u, dropped_counter_.total_partial());
1868 EXPECT_EQ(kSkipFrames_1 + kSkipFrames_2, dropped_counter_.total_dropped());
1869 EXPECT_EQ(kSkipFrames_1, dropped_counter_.total_smoothness_dropped());
1871 // Now skip over a few frames more frames which are affecting smoothness.
1872 reporting_controller_.SetThreadAffectsSmoothness(thread_type_compositor,
1874 const uint32_t kSkipFrames_3 = 10;
1875 for (uint32_t i = 0; i < kSkipFrames_3; ++i)
1876 IncrementCurrentId();
1877 SimulatePresentCompositorFrame(); // Present another frame.
1878 EXPECT_EQ(5u + kSkipFrames_1 + kSkipFrames_2 + kSkipFrames_3,
1879 dropped_counter_.total_frames());
1880 EXPECT_EQ(0u, dropped_counter_.total_partial());
1881 EXPECT_EQ(kSkipFrames_1 + kSkipFrames_2 + kSkipFrames_3,
1882 dropped_counter_.total_dropped());
1883 EXPECT_EQ(kSkipFrames_1 + kSkipFrames_3,
1884 dropped_counter_.total_smoothness_dropped());
1887 TEST_F(CompositorFrameReportingControllerTest,
1888 SkippedFramesFromClientRequestedThrottlingAreDropped) {
1889 // Submit and present two compositor frames.
1890 SimulatePresentCompositorFrame();
1891 EXPECT_EQ(1u, dropped_counter_.total_frames());
1892 EXPECT_EQ(0u, dropped_counter_.total_partial());
1893 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1895 SimulatePresentCompositorFrame();
1896 EXPECT_EQ(2u, dropped_counter_.total_frames());
1897 EXPECT_EQ(0u, dropped_counter_.total_partial());
1898 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1900 // Now skip over a few frames, and submit + present another frame.
1901 const uint32_t kTotalFrames = 5;
1902 const uint64_t kThrottledFrames = 4;
1903 for (uint32_t i = 0; i < kTotalFrames; ++i)
1904 IncrementCurrentId();
1905 args_.frames_throttled_since_last = kThrottledFrames;
1906 SimulatePresentCompositorFrame();
1907 EXPECT_EQ(3u + kTotalFrames - kThrottledFrames,
1908 dropped_counter_.total_frames());
1909 EXPECT_EQ(0u, dropped_counter_.total_partial());
1910 EXPECT_EQ(kTotalFrames - kThrottledFrames, dropped_counter_.total_dropped());
1913 TEST_F(CompositorFrameReportingControllerTest,
1914 DroppedFrameCountOnMainFrameAbort) {
1915 // Start a few begin-main-frames, but abort the main-frames due to no damage.
1916 for (int i = 0; i < 5; ++i) {
1917 SimulateBeginImplFrame();
1918 SimulateBeginMainFrame();
1919 reporting_controller_.OnFinishImplFrame(current_id_);
1920 reporting_controller_.BeginMainFrameAborted(
1921 current_id_, CommitEarlyOutReason::FINISHED_NO_UPDATES);
1923 EXPECT_EQ(0u, dropped_counter_.total_dropped());
1925 // Start a few begin-main-frames, but abort the main-frames due to no damage.
1926 for (int i = 0; i < 5; ++i) {
1927 SimulateBeginImplFrame();
1928 SimulateBeginMainFrame();
1929 reporting_controller_.OnFinishImplFrame(current_id_);
1930 reporting_controller_.BeginMainFrameAborted(
1931 current_id_, CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT);
1932 SimulateSubmitCompositorFrame({});
1934 SimulatePresentCompositorFrame();
1935 EXPECT_EQ(5u, dropped_counter_.total_dropped());
1938 // Verifies that presentation feedbacks that arrive out of order are handled
1939 // properly. See crbug.com/1195105 for more details.
1940 TEST_F(CompositorFrameReportingControllerTest,
1941 HandleOutOfOrderPresentationFeedback) {
1942 // Submit three compositor frames without sending back their presentation
1944 SimulateSubmitCompositorFrame({});
1946 SimulateSubmitCompositorFrame({});
1947 const uint32_t frame_token_2 = *current_token_;
1949 SimulateSubmitCompositorFrame({});
1950 const uint32_t frame_token_3 = *current_token_;
1952 // Send a failed presentation feedback for frame 2. This should only drop
1953 // frame 2 and leave frame 1 in the queue.
1954 viz::FrameTimingDetails details_2;
1955 details_2.presentation_feedback = {AdvanceNowByMs(10), base::TimeDelta(),
1956 gfx::PresentationFeedback::kFailure};
1957 reporting_controller_.DidPresentCompositorFrame(frame_token_2, details_2);
1958 DCHECK_EQ(1u, dropped_counter_.total_frames());
1959 DCHECK_EQ(1u, dropped_counter_.total_dropped());
1961 // Send a successful presentation feedback for frame 3. This should drop frame
1963 viz::FrameTimingDetails details_3;
1964 details_3.presentation_feedback.timestamp = AdvanceNowByMs(10);
1965 reporting_controller_.DidPresentCompositorFrame(frame_token_3, details_3);
1966 DCHECK_EQ(3u, dropped_counter_.total_frames());
1967 DCHECK_EQ(2u, dropped_counter_.total_dropped());
1970 TEST_F(CompositorFrameReportingControllerTest,
1971 NewMainThreadUpdateNotReportedAsDropped) {
1972 auto thread_type_main = SmoothEffectDrivingThread::kMain;
1973 reporting_controller_.SetThreadAffectsSmoothness(thread_type_main,
1974 /*affects_smoothness=*/true);
1975 dropped_counter_.OnFcpReceived();
1976 dropped_counter_.SetTimeFcpReceivedForTesting(args_.frame_time);
1978 SimulateBeginMainFrame();
1979 reporting_controller_.OnFinishImplFrame(current_id_);
1980 reporting_controller_.DidSubmitCompositorFrame(1u, AdvanceNowByMs(10),
1981 current_id_, {}, {},
1982 /*has_missing_content=*/false);
1983 viz::FrameTimingDetails details = {};
1984 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
1985 reporting_controller_.DidPresentCompositorFrame(1u, details);
1986 // Starts a new frame and submit it prior to commit
1988 SimulateCommit(nullptr);
1990 const auto previous_id = current_id_;
1992 SimulateBeginMainFrame();
1993 DCHECK_NE(previous_id, current_id_);
1994 reporting_controller_.OnFinishImplFrame(current_id_);
1996 // Starts a new frame and submit it prior to its commit, but the older frame
1997 // has new updates which would be activated and submitted now.
1998 reporting_controller_.WillActivate();
1999 reporting_controller_.DidActivate();
2001 reporting_controller_.DidSubmitCompositorFrame(2u, AdvanceNowByMs(10),
2002 current_id_, previous_id, {},
2003 /*has_missing_content=*/false);
2004 details.presentation_feedback.timestamp = AdvanceNowByMs(10);
2005 reporting_controller_.DidPresentCompositorFrame(2u, details);
2007 SimulateCommit(nullptr);
2008 SimulatePresentCompositorFrame();
2010 // There are two frames with partial updates
2011 EXPECT_EQ(2u, dropped_counter_.total_partial());
2012 // Which one is accompanied with new main thread update so only one affects
2014 EXPECT_EQ(1u, dropped_counter_.total_smoothness_dropped());
2017 TEST_F(CompositorFrameReportingControllerTest,
2018 NoUpdateCompositorWithJankyMain) {
2019 reporting_controller_.SetThreadAffectsSmoothness(
2020 SmoothEffectDrivingThread::kCompositor, /*affects_smoothness=*/true);
2021 reporting_controller_.SetThreadAffectsSmoothness(
2022 SmoothEffectDrivingThread::kMain, /*affects_smoothness=*/false);
2024 dropped_counter_.OnFcpReceived();
2025 dropped_counter_.SetTimeFcpReceivedForTesting(args_.frame_time);
2027 // Start a new frame and take it all the way to start the frame on the main
2028 // thread (i.e. 'begin main frame').
2029 SimulateBeginMainFrame();
2030 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
2031 EXPECT_EQ(0u, dropped_counter_.total_frames());
2033 // Terminate the frame without submitting a frame.
2034 reporting_controller_.OnFinishImplFrame(current_id_);
2035 reporting_controller_.DidNotProduceFrame(current_id_,
2036 FrameSkippedReason::kWaitingOnMain);
2037 EXPECT_EQ(0u, dropped_counter_.total_frames());
2039 // Main thread responds.
2041 EXPECT_EQ(1, reporting_controller_.ActiveReporters());
2042 EXPECT_EQ(0u, dropped_counter_.total_frames());
2044 // Start and submit a second frame.
2045 SimulateBeginImplFrame();
2046 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
2047 EXPECT_EQ(0u, dropped_counter_.total_frames());
2049 reporting_controller_.OnFinishImplFrame(current_id_);
2050 SimulatePresentCompositorFrame();
2051 EXPECT_EQ(0u, dropped_counter_.total_smoothness_dropped());
2052 EXPECT_EQ(3u, dropped_counter_.total_frames());
2055 TEST_F(CompositorFrameReportingControllerTest, MainFrameBeforeCommit) {
2056 viz::BeginFrameArgs args1 = SimulateBeginFrameArgs({1, 1});
2057 viz::BeginFrameArgs args2 = SimulateBeginFrameArgs({1, 2});
2058 viz::BeginFrameArgs args3 = SimulateBeginFrameArgs({1, 3});
2059 viz::BeginFrameArgs args4 = SimulateBeginFrameArgs({1, 4});
2062 reporting_controller_.WillBeginImplFrame(args1);
2063 reporting_controller_.WillBeginMainFrame(args1);
2064 reporting_controller_.NotifyReadyToCommit(nullptr);
2065 // Frame 1 is ready to commit, so we can pipeline frame 2.
2066 reporting_controller_.WillBeginImplFrame(args2);
2067 reporting_controller_.WillBeginMainFrame(args2);
2068 EXPECT_EQ(2, reporting_controller_.ActiveReporters());
2069 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2070 CompositorFrameReportingController::PipelineStage::kBeginMainFrame));
2071 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2072 CompositorFrameReportingController::PipelineStage::kReadyToCommit));
2075 reporting_controller_.WillCommit();
2076 reporting_controller_.DidCommit();
2077 // Frame 2 ready to commit
2078 reporting_controller_.NotifyReadyToCommit(nullptr);
2079 reporting_controller_.WillBeginImplFrame(args3);
2080 EXPECT_EQ(3, reporting_controller_.ActiveReporters());
2082 reporting_controller_.WillBeginMainFrame(args3);
2083 EXPECT_EQ(3, reporting_controller_.ActiveReporters());
2084 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2085 CompositorFrameReportingController::PipelineStage::kBeginMainFrame));
2086 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2087 CompositorFrameReportingController::PipelineStage::kReadyToCommit));
2088 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2089 CompositorFrameReportingController::PipelineStage::kCommit));
2092 reporting_controller_.WillActivate();
2093 reporting_controller_.DidActivate();
2095 reporting_controller_.WillCommit();
2096 reporting_controller_.DidCommit();
2097 // Frame 3 ready to commit
2098 reporting_controller_.NotifyReadyToCommit(nullptr);
2099 reporting_controller_.WillBeginImplFrame(args4);
2100 EXPECT_EQ(4, reporting_controller_.ActiveReporters());
2102 reporting_controller_.WillBeginMainFrame(args4);
2103 EXPECT_EQ(4, reporting_controller_.ActiveReporters());
2104 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2105 CompositorFrameReportingController::PipelineStage::kBeginMainFrame));
2106 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2107 CompositorFrameReportingController::PipelineStage::kReadyToCommit));
2108 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2109 CompositorFrameReportingController::PipelineStage::kCommit));
2110 EXPECT_TRUE(reporting_controller_.HasReporterAt(
2111 CompositorFrameReportingController::PipelineStage::kActivate));