diff options
Diffstat (limited to 'chromium/cc/metrics/compositor_frame_reporting_controller.cc')
-rw-r--r-- | chromium/cc/metrics/compositor_frame_reporting_controller.cc | 156 |
1 files changed, 79 insertions, 77 deletions
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.cc b/chromium/cc/metrics/compositor_frame_reporting_controller.cc index f996975f2d3..760207b87f0 100644 --- a/chromium/cc/metrics/compositor_frame_reporting_controller.cc +++ b/chromium/cc/metrics/compositor_frame_reporting_controller.cc @@ -5,30 +5,17 @@ #include "cc/metrics/compositor_frame_reporting_controller.h" #include "cc/metrics/compositor_frame_reporter.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/quads/compositor_frame_metadata.h" namespace cc { namespace { using StageType = CompositorFrameReporter::StageType; -RollingTimeDeltaHistory* GetStageHistory( - std::unique_ptr<RollingTimeDeltaHistory> stage_history_[], - StageType stage_type) { - return stage_history_[static_cast<int>(stage_type)].get(); -} - -static constexpr size_t kMaxHistorySize = 50; } // namespace CompositorFrameReportingController::CompositorFrameReportingController( bool is_single_threaded) - : is_single_threaded_(is_single_threaded) { - for (int i = 0; i < static_cast<int>( - CompositorFrameReporter::StageType::kStageTypeCount); - ++i) { - stage_history_[i] = - std::make_unique<RollingTimeDeltaHistory>(kMaxHistorySize); - } -} + : is_single_threaded_(is_single_threaded) {} CompositorFrameReportingController::~CompositorFrameReportingController() { base::TimeTicks now = Now(); @@ -72,53 +59,60 @@ void CompositorFrameReportingController::WillBeginImplFrame() { std::unique_ptr<CompositorFrameReporter> reporter = std::make_unique<CompositorFrameReporter>(&active_trackers_, is_single_threaded_); - reporter->StartStage( - CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame, - begin_time, - GetStageHistory(stage_history_, CompositorFrameReporter::StageType:: - kBeginImplFrameToSendBeginMainFrame)); + reporter->StartStage(StageType::kBeginImplFrameToSendBeginMainFrame, + begin_time); reporters_[PipelineStage::kBeginImplFrame] = std::move(reporter); } void CompositorFrameReportingController::WillBeginMainFrame() { - DCHECK(reporters_[PipelineStage::kBeginImplFrame]); - // We need to use .get() below because operator<< in std::unique_ptr is a - // C++20 feature. - DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(), - reporters_[PipelineStage::kBeginImplFrame].get()); - reporters_[PipelineStage::kBeginImplFrame]->StartStage( - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(), - GetStageHistory( - stage_history_, - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit)); - AdvanceReporterStage(PipelineStage::kBeginImplFrame, - PipelineStage::kBeginMainFrame); + if (reporters_[PipelineStage::kBeginImplFrame]) { + // We need to use .get() below because operator<< in std::unique_ptr is a + // C++20 feature. + DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(), + reporters_[PipelineStage::kBeginImplFrame].get()); + reporters_[PipelineStage::kBeginImplFrame]->StartStage( + StageType::kSendBeginMainFrameToCommit, Now()); + AdvanceReporterStage(PipelineStage::kBeginImplFrame, + PipelineStage::kBeginMainFrame); + } else { + // In this case we have already submitted the ImplFrame, but we received + // beginMain frame before next BeginImplFrame (Not reached the ImplFrame + // deadline yet). So will start a new reporter at BeginMainFrame. + std::unique_ptr<CompositorFrameReporter> reporter = + std::make_unique<CompositorFrameReporter>(&active_trackers_, + is_single_threaded_); + reporter->StartStage(StageType::kSendBeginMainFrameToCommit, Now()); + reporters_[PipelineStage::kBeginMainFrame] = std::move(reporter); + } } void CompositorFrameReportingController::BeginMainFrameAborted() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); - std::unique_ptr<CompositorFrameReporter> aborted_frame_reporter = - std::move(reporters_[PipelineStage::kBeginMainFrame]); - aborted_frame_reporter->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kMainFrameAborted, - Now()); + + auto& begin_main_reporter = reporters_[PipelineStage::kBeginMainFrame]; + begin_main_reporter->OnAbortBeginMainFrame(); + + // If the main-frame was aborted (e.g. there was no visible update), then + // advance to activate stage if the compositor has already made changes to + // the active tree (i.e. if impl-frame has finished). + if (begin_main_reporter->did_finish_impl_frame()) { + begin_main_reporter->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, Now()); + AdvanceReporterStage(PipelineStage::kBeginMainFrame, + PipelineStage::kActivate); + } } void CompositorFrameReportingController::WillCommit() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); - reporters_[PipelineStage::kBeginMainFrame]->StartStage( - CompositorFrameReporter::StageType::kCommit, Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType::kCommit)); + reporters_[PipelineStage::kBeginMainFrame]->StartStage(StageType::kCommit, + Now()); } void CompositorFrameReportingController::DidCommit() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); reporters_[PipelineStage::kBeginMainFrame]->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - GetStageHistory( - stage_history_, - CompositorFrameReporter::StageType::kEndCommitToActivation)); + StageType::kEndCommitToActivation, Now()); AdvanceReporterStage(PipelineStage::kBeginMainFrame, PipelineStage::kCommit); } @@ -132,10 +126,7 @@ void CompositorFrameReportingController::WillActivate() { DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_); if (!reporters_[PipelineStage::kCommit]) return; - reporters_[PipelineStage::kCommit]->StartStage( - CompositorFrameReporter::StageType::kActivation, Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType::kActivation)); + reporters_[PipelineStage::kCommit]->StartStage(StageType::kActivation, Now()); } void CompositorFrameReportingController::DidActivate() { @@ -144,50 +135,60 @@ void CompositorFrameReportingController::DidActivate() { if (!reporters_[PipelineStage::kCommit]) return; reporters_[PipelineStage::kCommit]->StartStage( - CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame, - Now(), - GetStageHistory(stage_history_, CompositorFrameReporter::StageType:: - kEndActivateToSubmitCompositorFrame)); + StageType::kEndActivateToSubmitCompositorFrame, Now()); AdvanceReporterStage(PipelineStage::kCommit, PipelineStage::kActivate); } void CompositorFrameReportingController::DidSubmitCompositorFrame( uint32_t frame_token) { + // If there is no reporter in active stage and there exists a finished + // BeginImplFrame reporter (i.e. if impl-frame has finished), then advance it + // to the activate stage. + if (!reporters_[PipelineStage::kActivate] && + reporters_[PipelineStage::kBeginImplFrame]) { + auto& begin_impl_frame = reporters_[PipelineStage::kBeginImplFrame]; + if (begin_impl_frame->did_finish_impl_frame()) { + begin_impl_frame->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, + begin_impl_frame->impl_frame_finish_time()); + AdvanceReporterStage(PipelineStage::kBeginImplFrame, + PipelineStage::kActivate); + } + } + if (!reporters_[PipelineStage::kActivate]) return; + std::unique_ptr<CompositorFrameReporter> submitted_reporter = std::move(reporters_[PipelineStage::kActivate]); - // If there are any other reporters active on the other stages of the - // pipeline then that means a new frame was started during the duration of - // this reporter and therefore the frame being tracked missed the deadline. - if (reporters_[PipelineStage::kBeginImplFrame] || - reporters_[PipelineStage::kBeginMainFrame] || - reporters_[PipelineStage::kCommit]) { - submitted_reporter->MissedSubmittedFrame(); - } submitted_reporter->StartStage( - CompositorFrameReporter::StageType:: - kSubmitCompositorFrameToPresentationCompositorFrame, - Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType:: - kSubmitCompositorFrameToPresentationCompositorFrame)); + StageType::kSubmitCompositorFrameToPresentationCompositorFrame, Now()); submitted_compositor_frames_.emplace_back(frame_token, std::move(submitted_reporter)); } -void CompositorFrameReportingController::DidNotProduceFrame() { - if (!reporters_[PipelineStage::kActivate]) - return; - reporters_[PipelineStage::kActivate]->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame, - Now()); - reporters_[PipelineStage::kActivate] = nullptr; +void CompositorFrameReportingController::OnFinishImplFrame() { + if (reporters_[PipelineStage::kBeginImplFrame]) { + reporters_[PipelineStage::kBeginImplFrame]->OnFinishImplFrame(Now()); + } else if (reporters_[PipelineStage::kBeginMainFrame]) { + auto& begin_main_reporter = reporters_[PipelineStage::kBeginMainFrame]; + begin_main_reporter->OnFinishImplFrame(Now()); + + // If the main-frame was aborted (e.g. there was no visible update), then + // advance to activate stage if the compositor has already made changes to + // the active tree (i.e. if impl-frame has finished). + if (begin_main_reporter->did_abort_main_frame()) { + begin_main_reporter->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, Now()); + AdvanceReporterStage(PipelineStage::kBeginMainFrame, + PipelineStage::kActivate); + } + } } void CompositorFrameReportingController::DidPresentCompositorFrame( uint32_t frame_token, - base::TimeTicks presentation_time) { + const viz::FrameTimingDetails& details) { while (!submitted_compositor_frames_.empty()) { auto submitted_frame = submitted_compositor_frames_.begin(); if (viz::FrameTokenGT(submitted_frame->frame_token, frame_token)) @@ -199,8 +200,9 @@ void CompositorFrameReportingController::DidPresentCompositorFrame( termination_status = CompositorFrameReporter::FrameTerminationStatus::kDidNotPresentFrame; - submitted_frame->reporter->TerminateFrame(termination_status, - presentation_time); + submitted_frame->reporter->SetVizBreakdown(details); + submitted_frame->reporter->TerminateFrame( + termination_status, details.presentation_feedback.timestamp); submitted_compositor_frames_.erase(submitted_frame); } } |