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

Side by Side Diff: cc/scheduler/compositor_timing_history.cc

Issue 1681393003: cc: Add MainAndImplFrameTimeDelta UMA. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: - active_tree_needs_first_draw_ = true Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 base::TimeDelta estimate, 213 base::TimeDelta estimate,
211 bool affects_estimate) override { 214 bool affects_estimate) override {
212 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Renderer", "Draw"); 215 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Renderer", "Draw");
213 DeprecatedDrawDurationUMA(duration, estimate); 216 DeprecatedDrawDurationUMA(duration, estimate);
214 } 217 }
215 218
216 void AddSwapToAckLatency(base::TimeDelta duration) override { 219 void AddSwapToAckLatency(base::TimeDelta duration) override {
217 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Renderer.SwapToAckLatency", 220 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Renderer.SwapToAckLatency",
218 duration); 221 duration);
219 } 222 }
223
224 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
225 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(
226 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta);
227 }
220 }; 228 };
221 229
222 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { 230 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
223 public: 231 public:
224 ~BrowserUMAReporter() override {} 232 ~BrowserUMAReporter() override {}
225 233
226 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override { 234 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {
227 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS( 235 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(
228 "Scheduling.Browser.BeginMainFrameIntervalCritical", interval); 236 "Scheduling.Browser.BeginMainFrameIntervalCritical", interval);
229 } 237 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 base::TimeDelta estimate, 299 base::TimeDelta estimate,
292 bool affects_estimate) override { 300 bool affects_estimate) override {
293 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Browser", "Draw"); 301 REPORT_COMPOSITOR_TIMING_HISTORY_UMA("Browser", "Draw");
294 DeprecatedDrawDurationUMA(duration, estimate); 302 DeprecatedDrawDurationUMA(duration, estimate);
295 } 303 }
296 304
297 void AddSwapToAckLatency(base::TimeDelta duration) override { 305 void AddSwapToAckLatency(base::TimeDelta duration) override {
298 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Browser.SwapToAckLatency", 306 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Browser.SwapToAckLatency",
299 duration); 307 duration);
300 } 308 }
309
310 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
311 UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(
312 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta);
313 }
301 }; 314 };
302 315
303 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { 316 class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
304 public: 317 public:
305 ~NullUMAReporter() override {} 318 ~NullUMAReporter() override {}
306 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} 319 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {}
307 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { 320 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override {
308 } 321 }
309 void AddCommitInterval(base::TimeDelta interval) override {} 322 void AddCommitInterval(base::TimeDelta interval) override {}
310 void AddDrawInterval(base::TimeDelta interval) override {} 323 void AddDrawInterval(base::TimeDelta interval) override {}
(...skipping 14 matching lines...) Expand all
325 void AddPrepareTilesDuration(base::TimeDelta duration, 338 void AddPrepareTilesDuration(base::TimeDelta duration,
326 base::TimeDelta estimate, 339 base::TimeDelta estimate,
327 bool affects_estimate) override {} 340 bool affects_estimate) override {}
328 void AddActivateDuration(base::TimeDelta duration, 341 void AddActivateDuration(base::TimeDelta duration,
329 base::TimeDelta estimate, 342 base::TimeDelta estimate,
330 bool affects_estimate) override {} 343 bool affects_estimate) override {}
331 void AddDrawDuration(base::TimeDelta duration, 344 void AddDrawDuration(base::TimeDelta duration,
332 base::TimeDelta estimate, 345 base::TimeDelta estimate,
333 bool affects_estimate) override {} 346 bool affects_estimate) override {}
334 void AddSwapToAckLatency(base::TimeDelta duration) override {} 347 void AddSwapToAckLatency(base::TimeDelta duration) override {}
348 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {}
335 }; 349 };
336 350
337 } // namespace 351 } // namespace
338 352
339 CompositorTimingHistory::CompositorTimingHistory( 353 CompositorTimingHistory::CompositorTimingHistory(
354 bool using_synchronous_renderer_compositor,
340 UMACategory uma_category, 355 UMACategory uma_category,
341 RenderingStatsInstrumentation* rendering_stats_instrumentation) 356 RenderingStatsInstrumentation* rendering_stats_instrumentation)
342 : enabled_(false), 357 : using_synchronous_renderer_compositor_(
358 using_synchronous_renderer_compositor),
359 enabled_(false),
343 did_send_begin_main_frame_(false), 360 did_send_begin_main_frame_(false),
344 begin_main_frame_needed_continuously_(false), 361 begin_main_frame_needed_continuously_(false),
345 begin_main_frame_committing_continuously_(false), 362 begin_main_frame_committing_continuously_(false),
346 compositor_drawing_continuously_(false), 363 compositor_drawing_continuously_(false),
347 begin_main_frame_sent_to_commit_duration_history_(kDurationHistorySize), 364 begin_main_frame_sent_to_commit_duration_history_(kDurationHistorySize),
348 begin_main_frame_queue_duration_history_(kDurationHistorySize), 365 begin_main_frame_queue_duration_history_(kDurationHistorySize),
349 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), 366 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize),
350 begin_main_frame_queue_duration_not_critical_history_( 367 begin_main_frame_queue_duration_not_critical_history_(
351 kDurationHistorySize), 368 kDurationHistorySize),
352 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), 369 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize),
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 } 488 }
472 489
473 base::TimeDelta CompositorTimingHistory::ActivateDurationEstimate() const { 490 base::TimeDelta CompositorTimingHistory::ActivateDurationEstimate() const {
474 return activate_duration_history_.Percentile(kActivateEstimationPercentile); 491 return activate_duration_history_.Percentile(kActivateEstimationPercentile);
475 } 492 }
476 493
477 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { 494 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const {
478 return draw_duration_history_.Percentile(kDrawEstimationPercentile); 495 return draw_duration_history_.Percentile(kDrawEstimationPercentile);
479 } 496 }
480 497
498 void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() {
499 // After we get a new output surface, we won't get a spurious
500 // swap ack from the old output surface.
501 swap_start_time_ = base::TimeTicks();
502 }
503
481 void CompositorTimingHistory::WillBeginImplFrame( 504 void CompositorTimingHistory::WillBeginImplFrame(
482 bool new_active_tree_is_likely) { 505 bool new_active_tree_is_likely) {
483 // The check for whether a BeginMainFrame was sent anytime between two 506 // The check for whether a BeginMainFrame was sent anytime between two
484 // BeginImplFrames protects us from not detecting a fast main thread that 507 // BeginImplFrames protects us from not detecting a fast main thread that
485 // does all it's work and goes idle in between BeginImplFrames. 508 // does all it's work and goes idle in between BeginImplFrames.
486 // For example, this may happen if an animation is being driven with 509 // For example, this may happen if an animation is being driven with
487 // setInterval(17) or if input events just happen to arrive in the 510 // setInterval(17) or if input events just happen to arrive in the
488 // middle of every frame. 511 // middle of every frame.
489 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { 512 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) {
490 SetBeginMainFrameNeededContinuously(false); 513 SetBeginMainFrameNeededContinuously(false);
491 SetBeginMainFrameCommittingContinuously(false); 514 SetBeginMainFrameCommittingContinuously(false);
492 } 515 }
493 516
494 did_send_begin_main_frame_ = false; 517 did_send_begin_main_frame_ = false;
495 } 518 }
496 519
497 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { 520 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) {
498 if (!needs_redraw) 521 if (!needs_redraw)
499 SetCompositorDrawingContinuously(false); 522 SetCompositorDrawingContinuously(false);
500 } 523 }
501 524
502 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { 525 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() {
503 SetBeginMainFrameNeededContinuously(false); 526 SetBeginMainFrameNeededContinuously(false);
504 SetBeginMainFrameCommittingContinuously(false); 527 SetBeginMainFrameCommittingContinuously(false);
505 SetCompositorDrawingContinuously(false); 528 SetCompositorDrawingContinuously(false);
506 } 529 }
507 530
508 void CompositorTimingHistory::WillBeginMainFrame(bool on_critical_path) { 531 void CompositorTimingHistory::WillBeginMainFrame(
532 bool on_critical_path,
533 base::TimeTicks main_frame_time) {
509 DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_); 534 DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_);
535 DCHECK_EQ(base::TimeTicks(), begin_main_frame_frame_time_);
536
510 begin_main_frame_on_critical_path_ = on_critical_path; 537 begin_main_frame_on_critical_path_ = on_critical_path;
511 begin_main_frame_sent_time_ = Now(); 538 begin_main_frame_sent_time_ = Now();
539 begin_main_frame_frame_time_ = main_frame_time;
512 540
513 did_send_begin_main_frame_ = true; 541 did_send_begin_main_frame_ = true;
514 SetBeginMainFrameNeededContinuously(true); 542 SetBeginMainFrameNeededContinuously(true);
515 } 543 }
516 544
517 void CompositorTimingHistory::BeginMainFrameStarted( 545 void CompositorTimingHistory::BeginMainFrameStarted(
518 base::TimeTicks main_thread_start_time) { 546 base::TimeTicks main_thread_start_time) {
519 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); 547 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_);
520 DCHECK_EQ(base::TimeTicks(), begin_main_frame_start_time_); 548 DCHECK_EQ(base::TimeTicks(), begin_main_frame_start_time_);
521 begin_main_frame_start_time_ = main_thread_start_time; 549 begin_main_frame_start_time_ = main_thread_start_time;
522 } 550 }
523 551
524 void CompositorTimingHistory::BeginMainFrameAborted() { 552 void CompositorTimingHistory::BeginMainFrameAborted() {
525 SetBeginMainFrameCommittingContinuously(false); 553 SetBeginMainFrameCommittingContinuously(false);
526 DidBeginMainFrame(); 554 DidBeginMainFrame();
555 begin_main_frame_frame_time_ = base::TimeTicks();
527 } 556 }
528 557
529 void CompositorTimingHistory::DidCommit() { 558 void CompositorTimingHistory::DidCommit() {
559 DCHECK_EQ(base::TimeTicks(), pending_tree_main_frame_time_);
530 SetBeginMainFrameCommittingContinuously(true); 560 SetBeginMainFrameCommittingContinuously(true);
531 DidBeginMainFrame(); 561 DidBeginMainFrame();
562 pending_tree_main_frame_time_ = begin_main_frame_frame_time_;
563 begin_main_frame_frame_time_ = base::TimeTicks();
532 } 564 }
533 565
534 void CompositorTimingHistory::DidBeginMainFrame() { 566 void CompositorTimingHistory::DidBeginMainFrame() {
535 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); 567 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_);
536 568
537 begin_main_frame_end_time_ = Now(); 569 begin_main_frame_end_time_ = Now();
538 570
539 // If the BeginMainFrame start time isn't know, assume it was immediate 571 // If the BeginMainFrame start time isn't know, assume it was immediate
540 // for scheduling purposes, but don't report it for UMA to avoid skewing 572 // for scheduling purposes, but don't report it for UMA to avoid skewing
541 // the results. 573 // the results.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 691
660 void CompositorTimingHistory::DidActivate() { 692 void CompositorTimingHistory::DidActivate() {
661 DCHECK_NE(base::TimeTicks(), activate_start_time_); 693 DCHECK_NE(base::TimeTicks(), activate_start_time_);
662 base::TimeDelta activate_duration = Now() - activate_start_time_; 694 base::TimeDelta activate_duration = Now() - activate_start_time_;
663 695
664 uma_reporter_->AddActivateDuration(activate_duration, 696 uma_reporter_->AddActivateDuration(activate_duration,
665 ActivateDurationEstimate(), enabled_); 697 ActivateDurationEstimate(), enabled_);
666 if (enabled_) 698 if (enabled_)
667 activate_duration_history_.InsertSample(activate_duration); 699 activate_duration_history_.InsertSample(activate_duration);
668 700
701 // The synchronous compositor doesn't necessarily draw every new active tree.
702 if (!using_synchronous_renderer_compositor_)
703 DCHECK_EQ(base::TimeTicks(), active_tree_main_frame_time_);
704 active_tree_main_frame_time_ = pending_tree_main_frame_time_;
705
669 activate_start_time_ = base::TimeTicks(); 706 activate_start_time_ = base::TimeTicks();
707 pending_tree_main_frame_time_ = base::TimeTicks();
670 } 708 }
671 709
672 void CompositorTimingHistory::WillDraw() { 710 void CompositorTimingHistory::WillDraw() {
673 DCHECK_EQ(base::TimeTicks(), draw_start_time_); 711 DCHECK_EQ(base::TimeTicks(), draw_start_time_);
674 draw_start_time_ = Now(); 712 draw_start_time_ = Now();
675 } 713 }
676 714
677 void CompositorTimingHistory::DidDraw(bool used_new_active_tree) { 715 void CompositorTimingHistory::DrawAborted() {
716 active_tree_main_frame_time_ = base::TimeTicks();
717 }
718
719 void CompositorTimingHistory::DidDraw(bool used_new_active_tree,
720 bool main_thread_missed_last_deadline,
721 base::TimeTicks impl_frame_time) {
678 DCHECK_NE(base::TimeTicks(), draw_start_time_); 722 DCHECK_NE(base::TimeTicks(), draw_start_time_);
679 base::TimeTicks draw_end_time = Now(); 723 base::TimeTicks draw_end_time = Now();
680 base::TimeDelta draw_duration = draw_end_time - draw_start_time_; 724 base::TimeDelta draw_duration = draw_end_time - draw_start_time_;
681 725
682 // Before adding the new data point to the timing history, see what we would 726 // Before adding the new data point to the timing history, see what we would
683 // have predicted for this frame. This allows us to keep track of the accuracy 727 // have predicted for this frame. This allows us to keep track of the accuracy
684 // of our predictions. 728 // of our predictions.
685 base::TimeDelta draw_estimate = DrawDurationEstimate(); 729 base::TimeDelta draw_estimate = DrawDurationEstimate();
686 rendering_stats_instrumentation_->AddDrawDuration(draw_duration, 730 rendering_stats_instrumentation_->AddDrawDuration(draw_duration,
687 draw_estimate); 731 draw_estimate);
688 732
689 uma_reporter_->AddDrawDuration(draw_duration, draw_estimate, enabled_); 733 uma_reporter_->AddDrawDuration(draw_duration, draw_estimate, enabled_);
690 734
691 if (enabled_) { 735 if (enabled_) {
692 draw_duration_history_.InsertSample(draw_duration); 736 draw_duration_history_.InsertSample(draw_duration);
693 } 737 }
694 738
695 SetCompositorDrawingContinuously(true); 739 SetCompositorDrawingContinuously(true);
696 if (!draw_end_time_prev_.is_null()) { 740 if (!draw_end_time_prev_.is_null()) {
697 base::TimeDelta draw_interval = draw_end_time - draw_end_time_prev_; 741 base::TimeDelta draw_interval = draw_end_time - draw_end_time_prev_;
698 uma_reporter_->AddDrawInterval(draw_interval); 742 uma_reporter_->AddDrawInterval(draw_interval);
699 } 743 }
700 draw_end_time_prev_ = draw_end_time; 744 draw_end_time_prev_ = draw_end_time;
701 745
702 if (begin_main_frame_committing_continuously_ && used_new_active_tree) { 746 if (used_new_active_tree) {
703 if (!new_active_tree_draw_end_time_prev_.is_null()) { 747 DCHECK_NE(base::TimeTicks(), active_tree_main_frame_time_);
704 base::TimeDelta draw_interval = 748 base::TimeDelta main_and_impl_delta =
705 draw_end_time - new_active_tree_draw_end_time_prev_; 749 impl_frame_time - active_tree_main_frame_time_;
706 uma_reporter_->AddCommitInterval(draw_interval); 750 DCHECK_GE(main_and_impl_delta, base::TimeDelta());
751 if (!using_synchronous_renderer_compositor_) {
752 DCHECK_EQ(main_thread_missed_last_deadline,
753 !main_and_impl_delta.is_zero());
707 } 754 }
708 new_active_tree_draw_end_time_prev_ = draw_end_time; 755 uma_reporter_->AddMainAndImplFrameTimeDelta(main_and_impl_delta);
756 active_tree_main_frame_time_ = base::TimeTicks();
757
758 if (begin_main_frame_committing_continuously_) {
759 if (!new_active_tree_draw_end_time_prev_.is_null()) {
760 base::TimeDelta draw_interval =
761 draw_end_time - new_active_tree_draw_end_time_prev_;
762 uma_reporter_->AddCommitInterval(draw_interval);
763 }
764 new_active_tree_draw_end_time_prev_ = draw_end_time;
765 }
709 } 766 }
710 767
711 draw_start_time_ = base::TimeTicks(); 768 draw_start_time_ = base::TimeTicks();
712 } 769 }
713 770
714 void CompositorTimingHistory::DidSwapBuffers() { 771 void CompositorTimingHistory::DidSwapBuffers() {
715 DCHECK_EQ(base::TimeTicks(), swap_start_time_); 772 DCHECK_EQ(base::TimeTicks(), swap_start_time_);
716 swap_start_time_ = Now(); 773 swap_start_time_ = Now();
717 } 774 }
718 775
719 void CompositorTimingHistory::DidSwapBuffersComplete() { 776 void CompositorTimingHistory::DidSwapBuffersComplete() {
720 DCHECK_NE(base::TimeTicks(), swap_start_time_); 777 DCHECK_NE(base::TimeTicks(), swap_start_time_);
721 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; 778 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_;
722 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); 779 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration);
723 swap_start_time_ = base::TimeTicks(); 780 swap_start_time_ = base::TimeTicks();
724 } 781 }
725 782
726 void CompositorTimingHistory::DidSwapBuffersReset() {
727 swap_start_time_ = base::TimeTicks();
728 }
729
730 } // namespace cc 783 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/compositor_timing_history.h ('k') | cc/scheduler/compositor_timing_history_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698