OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/compositor_timing_history.h" | 5 #include "cc/scheduler/compositor_timing_history.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
43 virtual void AddPrepareTilesDuration(base::TimeDelta duration, | 43 virtual void AddPrepareTilesDuration(base::TimeDelta duration, |
44 base::TimeDelta estimate, | 44 base::TimeDelta estimate, |
45 bool affects_estimate) = 0; | 45 bool affects_estimate) = 0; |
46 virtual void AddActivateDuration(base::TimeDelta duration, | 46 virtual void AddActivateDuration(base::TimeDelta duration, |
47 base::TimeDelta estimate, | 47 base::TimeDelta estimate, |
48 bool affects_estimate) = 0; | 48 bool affects_estimate) = 0; |
49 virtual void AddDrawDuration(base::TimeDelta duration, | 49 virtual void AddDrawDuration(base::TimeDelta duration, |
50 base::TimeDelta estimate, | 50 base::TimeDelta estimate, |
51 bool affects_estimate) = 0; | 51 bool affects_estimate) = 0; |
52 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; | 52 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; |
53 | |
54 // Synchronization measurements | |
55 virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; | |
53 }; | 56 }; |
54 | 57 |
55 namespace { | 58 namespace { |
56 | 59 |
57 // Using the 90th percentile will disable latency recovery | 60 // Using the 90th percentile will disable latency recovery |
58 // if we are missing the deadline approximately ~6 times per | 61 // if we are missing the deadline approximately ~6 times per |
59 // second. | 62 // second. |
60 // TODO(brianderson): Fine tune the percentiles below. | 63 // TODO(brianderson): Fine tune the percentiles below. |
61 const size_t kDurationHistorySize = 60; | 64 const size_t kDurationHistorySize = 60; |
62 const double kBeginMainFrameToCommitEstimationPercentile = 90.0; | 65 const double kBeginMainFrameToCommitEstimationPercentile = 90.0; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
209 base::TimeDelta estimate, | 212 base::TimeDelta estimate, |
210 bool affects_estimate) override { | 213 bool affects_estimate) override { |
211 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Renderer", "Draw"); | 214 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Renderer", "Draw"); |
212 DeprecatedDrawDurationUMA(duration, estimate); | 215 DeprecatedDrawDurationUMA(duration, estimate); |
213 } | 216 } |
214 | 217 |
215 void AddSwapToAckLatency(base::TimeDelta duration) override { | 218 void AddSwapToAckLatency(base::TimeDelta duration) override { |
216 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Renderer.SwapToAckLatency", | 219 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Renderer.SwapToAckLatency", |
217 duration); | 220 duration); |
218 } | 221 } |
222 | |
223 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { | |
224 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS( | |
225 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta); | |
226 } | |
219 }; | 227 }; |
220 | 228 |
221 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { | 229 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { |
222 public: | 230 public: |
223 ~BrowserUMAReporter() override {} | 231 ~BrowserUMAReporter() override {} |
224 | 232 |
225 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override { | 233 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override { |
226 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS( | 234 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS( |
227 "Scheduling.Browser.BeginMainFrameIntervalCritical", interval); | 235 "Scheduling.Browser.BeginMainFrameIntervalCritical", interval); |
228 } | 236 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 base::TimeDelta estimate, | 298 base::TimeDelta estimate, |
291 bool affects_estimate) override { | 299 bool affects_estimate) override { |
292 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Browser", "Draw"); | 300 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Browser", "Draw"); |
293 DeprecatedDrawDurationUMA(duration, estimate); | 301 DeprecatedDrawDurationUMA(duration, estimate); |
294 } | 302 } |
295 | 303 |
296 void AddSwapToAckLatency(base::TimeDelta duration) override { | 304 void AddSwapToAckLatency(base::TimeDelta duration) override { |
297 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Browser.SwapToAckLatency", | 305 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Browser.SwapToAckLatency", |
298 duration); | 306 duration); |
299 } | 307 } |
308 | |
309 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { | |
310 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS( | |
311 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta); | |
312 } | |
300 }; | 313 }; |
301 | 314 |
302 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { | 315 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { |
303 public: | 316 public: |
304 ~NullUMAReporter() override {} | 317 ~NullUMAReporter() override {} |
305 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} | 318 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} |
306 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { | 319 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { |
307 } | 320 } |
308 void AddCommitInterval(base::TimeDelta interval) override {} | 321 void AddCommitInterval(base::TimeDelta interval) override {} |
309 void AddDrawInterval(base::TimeDelta interval) override {} | 322 void AddDrawInterval(base::TimeDelta interval) override {} |
(...skipping 14 matching lines...) Expand all Loading... | |
324 void AddPrepareTilesDuration(base::TimeDelta duration, | 337 void AddPrepareTilesDuration(base::TimeDelta duration, |
325 base::TimeDelta estimate, | 338 base::TimeDelta estimate, |
326 bool affects_estimate) override {} | 339 bool affects_estimate) override {} |
327 void AddActivateDuration(base::TimeDelta duration, | 340 void AddActivateDuration(base::TimeDelta duration, |
328 base::TimeDelta estimate, | 341 base::TimeDelta estimate, |
329 bool affects_estimate) override {} | 342 bool affects_estimate) override {} |
330 void AddDrawDuration(base::TimeDelta duration, | 343 void AddDrawDuration(base::TimeDelta duration, |
331 base::TimeDelta estimate, | 344 base::TimeDelta estimate, |
332 bool affects_estimate) override {} | 345 bool affects_estimate) override {} |
333 void AddSwapToAckLatency(base::TimeDelta duration) override {} | 346 void AddSwapToAckLatency(base::TimeDelta duration) override {} |
347 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} | |
334 }; | 348 }; |
335 | 349 |
336 } // namespace | 350 } // namespace |
337 | 351 |
338 CompositorTimingHistory::CompositorTimingHistory( | 352 CompositorTimingHistory::CompositorTimingHistory( |
339 UMACategory uma_category, | 353 UMACategory uma_category, |
340 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 354 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
341 : enabled_(false), | 355 : enabled_(false), |
342 did_send_begin_main_frame_(false), | 356 did_send_begin_main_frame_(false), |
343 begin_main_frame_needed_continuously_(false), | 357 begin_main_frame_needed_continuously_(false), |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 if (!needs_redraw) | 498 if (!needs_redraw) |
485 SetCompositorDrawingContinuously(false); | 499 SetCompositorDrawingContinuously(false); |
486 } | 500 } |
487 | 501 |
488 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { | 502 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { |
489 SetBeginMainFrameNeededContinuously(false); | 503 SetBeginMainFrameNeededContinuously(false); |
490 SetBeginMainFrameCommittingContinuously(false); | 504 SetBeginMainFrameCommittingContinuously(false); |
491 SetCompositorDrawingContinuously(false); | 505 SetCompositorDrawingContinuously(false); |
492 } | 506 } |
493 | 507 |
494 void CompositorTimingHistory::WillBeginMainFrame(bool on_critical_path) { | 508 void CompositorTimingHistory::WillBeginMainFrame( |
509 bool on_critical_path, | |
510 base::TimeTicks main_frame_time) { | |
495 DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_); | 511 DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_); |
512 DCHECK_EQ(base::TimeTicks(), begin_main_frame_frame_time_); | |
496 begin_main_frame_on_critical_path_ = on_critical_path; | 513 begin_main_frame_on_critical_path_ = on_critical_path; |
497 begin_main_frame_sent_time_ = Now(); | 514 begin_main_frame_sent_time_ = Now(); |
515 begin_main_frame_frame_time_ = main_frame_time; | |
498 | 516 |
499 did_send_begin_main_frame_ = true; | 517 did_send_begin_main_frame_ = true; |
500 SetBeginMainFrameNeededContinuously(true); | 518 SetBeginMainFrameNeededContinuously(true); |
501 } | 519 } |
502 | 520 |
503 void CompositorTimingHistory::BeginMainFrameStarted( | 521 void CompositorTimingHistory::BeginMainFrameStarted( |
504 base::TimeTicks main_thread_start_time) { | 522 base::TimeTicks main_thread_start_time) { |
505 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); | 523 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); |
506 DCHECK_EQ(base::TimeTicks(), begin_main_frame_start_time_); | 524 DCHECK_EQ(base::TimeTicks(), begin_main_frame_start_time_); |
507 begin_main_frame_start_time_ = main_thread_start_time; | 525 begin_main_frame_start_time_ = main_thread_start_time; |
508 } | 526 } |
509 | 527 |
510 void CompositorTimingHistory::BeginMainFrameAborted() { | 528 void CompositorTimingHistory::BeginMainFrameAborted() { |
511 SetBeginMainFrameCommittingContinuously(false); | 529 SetBeginMainFrameCommittingContinuously(false); |
512 DidBeginMainFrame(); | 530 DidBeginMainFrame(); |
531 begin_main_frame_frame_time_ = base::TimeTicks(); | |
513 } | 532 } |
514 | 533 |
515 void CompositorTimingHistory::DidCommit() { | 534 void CompositorTimingHistory::DidCommit() { |
535 DCHECK_EQ(base::TimeTicks(), pending_tree_main_frame_time_); | |
516 SetBeginMainFrameCommittingContinuously(true); | 536 SetBeginMainFrameCommittingContinuously(true); |
517 DidBeginMainFrame(); | 537 DidBeginMainFrame(); |
538 pending_tree_main_frame_time_ = begin_main_frame_frame_time_; | |
539 begin_main_frame_frame_time_ = base::TimeTicks(); | |
518 } | 540 } |
519 | 541 |
520 void CompositorTimingHistory::DidBeginMainFrame() { | 542 void CompositorTimingHistory::DidBeginMainFrame() { |
521 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); | 543 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); |
522 | 544 |
523 begin_main_frame_end_time_ = Now(); | 545 begin_main_frame_end_time_ = Now(); |
524 | 546 |
525 // If the BeginMainFrame start time isn't know, assume it was immediate | 547 // If the BeginMainFrame start time isn't know, assume it was immediate |
526 // for scheduling purposes, but don't report it for UMA to avoid skewing | 548 // for scheduling purposes, but don't report it for UMA to avoid skewing |
527 // the results. | 549 // the results. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
644 void CompositorTimingHistory::DidActivate() { | 666 void CompositorTimingHistory::DidActivate() { |
645 DCHECK_NE(base::TimeTicks(), activate_start_time_); | 667 DCHECK_NE(base::TimeTicks(), activate_start_time_); |
646 base::TimeDelta activate_duration = Now() - activate_start_time_; | 668 base::TimeDelta activate_duration = Now() - activate_start_time_; |
647 | 669 |
648 uma_reporter_->AddActivateDuration(activate_duration, | 670 uma_reporter_->AddActivateDuration(activate_duration, |
649 ActivateDurationEstimate(), enabled_); | 671 ActivateDurationEstimate(), enabled_); |
650 if (enabled_) | 672 if (enabled_) |
651 activate_duration_history_.InsertSample(activate_duration); | 673 activate_duration_history_.InsertSample(activate_duration); |
652 | 674 |
653 activate_start_time_ = base::TimeTicks(); | 675 activate_start_time_ = base::TimeTicks(); |
676 | |
677 DCHECK_EQ(base::TimeTicks(), active_tree_main_frame_time_); | |
678 active_tree_main_frame_time_ = pending_tree_main_frame_time_; | |
679 pending_tree_main_frame_time_ = base::TimeTicks(); | |
654 } | 680 } |
655 | 681 |
656 void CompositorTimingHistory::WillDraw() { | 682 void CompositorTimingHistory::WillDraw() { |
657 DCHECK_EQ(base::TimeTicks(), draw_start_time_); | 683 DCHECK_EQ(base::TimeTicks(), draw_start_time_); |
658 draw_start_time_ = Now(); | 684 draw_start_time_ = Now(); |
659 } | 685 } |
660 | 686 |
661 void CompositorTimingHistory::DidDraw(bool used_new_active_tree) { | 687 void CompositorTimingHistory::DidDraw(bool used_new_active_tree, |
688 bool main_thread_missed_last_deadline, | |
689 base::TimeTicks impl_frame_time) { | |
662 DCHECK_NE(base::TimeTicks(), draw_start_time_); | 690 DCHECK_NE(base::TimeTicks(), draw_start_time_); |
663 base::TimeTicks draw_end_time = Now(); | 691 base::TimeTicks draw_end_time = Now(); |
664 base::TimeDelta draw_duration = draw_end_time - draw_start_time_; | 692 base::TimeDelta draw_duration = draw_end_time - draw_start_time_; |
665 | 693 |
666 // Before adding the new data point to the timing history, see what we would | 694 // Before adding the new data point to the timing history, see what we would |
667 // have predicted for this frame. This allows us to keep track of the accuracy | 695 // have predicted for this frame. This allows us to keep track of the accuracy |
668 // of our predictions. | 696 // of our predictions. |
669 base::TimeDelta draw_estimate = DrawDurationEstimate(); | 697 base::TimeDelta draw_estimate = DrawDurationEstimate(); |
670 rendering_stats_instrumentation_->AddDrawDuration(draw_duration, | 698 rendering_stats_instrumentation_->AddDrawDuration(draw_duration, |
671 draw_estimate); | 699 draw_estimate); |
672 | 700 |
673 uma_reporter_->AddDrawDuration(draw_duration, draw_estimate, enabled_); | 701 uma_reporter_->AddDrawDuration(draw_duration, draw_estimate, enabled_); |
674 | 702 |
675 if (enabled_) { | 703 if (enabled_) { |
676 draw_duration_history_.InsertSample(draw_duration); | 704 draw_duration_history_.InsertSample(draw_duration); |
677 } | 705 } |
678 | 706 |
679 SetCompositorDrawingContinuously(true); | 707 SetCompositorDrawingContinuously(true); |
680 if (!draw_end_time_prev_.is_null()) { | 708 if (!draw_end_time_prev_.is_null()) { |
681 base::TimeDelta draw_interval = draw_end_time - draw_end_time_prev_; | 709 base::TimeDelta draw_interval = draw_end_time - draw_end_time_prev_; |
682 uma_reporter_->AddDrawInterval(draw_interval); | 710 uma_reporter_->AddDrawInterval(draw_interval); |
683 } | 711 } |
684 draw_end_time_prev_ = draw_end_time; | 712 draw_end_time_prev_ = draw_end_time; |
685 | 713 |
686 if (begin_main_frame_committing_continuously_ && used_new_active_tree) { | 714 if (used_new_active_tree) { |
687 if (!new_active_tree_draw_end_time_prev_.is_null()) { | 715 DCHECK_NE(base::TimeTicks(), active_tree_main_frame_time_); |
688 base::TimeDelta draw_interval = | 716 base::TimeDelta main_and_impl_delta = |
689 draw_end_time - new_active_tree_draw_end_time_prev_; | 717 impl_frame_time - active_tree_main_frame_time_; |
690 uma_reporter_->AddCommitInterval(draw_interval); | 718 DCHECK_GE(main_and_impl_delta, base::TimeDelta()); |
719 DCHECK_EQ(main_thread_missed_last_deadline, !main_and_impl_delta.is_zero()); | |
brianderson
2016/02/11 01:43:45
Good thing we tried recording the delta. I added t
| |
720 uma_reporter_->AddMainAndImplFrameTimeDelta(main_and_impl_delta); | |
721 active_tree_main_frame_time_ = base::TimeTicks(); | |
722 | |
723 if (begin_main_frame_committing_continuously_) { | |
724 if (!new_active_tree_draw_end_time_prev_.is_null()) { | |
725 base::TimeDelta draw_interval = | |
726 draw_end_time - new_active_tree_draw_end_time_prev_; | |
727 uma_reporter_->AddCommitInterval(draw_interval); | |
728 } | |
729 new_active_tree_draw_end_time_prev_ = draw_end_time; | |
691 } | 730 } |
692 new_active_tree_draw_end_time_prev_ = draw_end_time; | |
693 } | 731 } |
694 | 732 |
695 draw_start_time_ = base::TimeTicks(); | 733 draw_start_time_ = base::TimeTicks(); |
696 } | 734 } |
697 | 735 |
698 void CompositorTimingHistory::DidSwapBuffers() { | 736 void CompositorTimingHistory::DidSwapBuffers() { |
699 DCHECK_EQ(base::TimeTicks(), swap_start_time_); | 737 DCHECK_EQ(base::TimeTicks(), swap_start_time_); |
700 swap_start_time_ = Now(); | 738 swap_start_time_ = Now(); |
701 } | 739 } |
702 | 740 |
703 void CompositorTimingHistory::DidSwapBuffersComplete() { | 741 void CompositorTimingHistory::DidSwapBuffersComplete() { |
704 DCHECK_NE(base::TimeTicks(), swap_start_time_); | 742 DCHECK_NE(base::TimeTicks(), swap_start_time_); |
705 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; | 743 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; |
706 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); | 744 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); |
707 swap_start_time_ = base::TimeTicks(); | 745 swap_start_time_ = base::TimeTicks(); |
708 } | 746 } |
709 | 747 |
710 void CompositorTimingHistory::DidSwapBuffersReset() { | 748 void CompositorTimingHistory::DidSwapBuffersReset() { |
711 swap_start_time_ = base::TimeTicks(); | 749 swap_start_time_ = base::TimeTicks(); |
712 } | 750 } |
713 | 751 |
714 } // namespace cc | 752 } // namespace cc |
OLD | NEW |