Commit 2fcffb28 authored by behdad's avatar behdad Committed by Commit Bot

Record latency for Impl thread in case of no begin main frame.

This CL reports the latency in case of no begin main frame.
This can happen in any of the scenarios below:

1) WillBeginImplFrame -> DidFinishImplFrame -> DidSubmitCompositorFrame

2) WillBeginImplFrame -> WillBeginMainFrame -> BeginMainFrameAborted ->
DidFinishImplFrame -> DidSubmitCompositorFrame

3) WillBeginImplFrame -> WillBeginMainFrame -> DidFinishImplFrame ->
BeginMainFrameAborted -> DidSubmitCompositorFrame

In these cases there will be no latency to report for stages of:
- SendBeginMainFrameToCommit
- Commit
- EndCommitToActivation
But the latency will be reported for the remaining stages.

Bug: chromium:1003038
Change-Id: Id0d6a65603b2b15a0ee04a6974a4bd0b2a5a803b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1799026
Commit-Queue: Behdad Bakhshinategh <behdadb@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705964}
parent 97691abc
...@@ -153,6 +153,17 @@ void CompositorFrameReporter::TerminateFrame( ...@@ -153,6 +153,17 @@ void CompositorFrameReporter::TerminateFrame(
EndCurrentStage(frame_termination_time_); EndCurrentStage(frame_termination_time_);
} }
void CompositorFrameReporter::OnFinishImplFrame(base::TimeTicks timestamp) {
DCHECK(!did_finish_impl_frame_);
did_finish_impl_frame_ = true;
impl_frame_finish_time_ = timestamp;
}
void CompositorFrameReporter::OnAbortBeginMainFrame() {
did_abort_main_frame_ = false;
}
void CompositorFrameReporter::SetVizBreakdown( void CompositorFrameReporter::SetVizBreakdown(
const viz::FrameTimingDetails& viz_breakdown) { const viz::FrameTimingDetails& viz_breakdown) {
DCHECK(current_stage_.viz_breakdown.received_compositor_frame_timestamp DCHECK(current_stage_.viz_breakdown.received_compositor_frame_timestamp
......
...@@ -111,6 +111,14 @@ class CC_EXPORT CompositorFrameReporter { ...@@ -111,6 +111,14 @@ class CC_EXPORT CompositorFrameReporter {
int StageHistorySizeForTesting() { return stage_history_.size(); } int StageHistorySizeForTesting() { return stage_history_.size(); }
void OnFinishImplFrame(base::TimeTicks timestamp);
void OnAbortBeginMainFrame();
bool did_finish_impl_frame() const { return did_finish_impl_frame_; }
bool did_abort_main_frame() const { return did_abort_main_frame_; }
base::TimeTicks impl_frame_finish_time() const {
return impl_frame_finish_time_;
}
protected: protected:
struct StageData { struct StageData {
StageType stage_type; StageType stage_type;
...@@ -161,6 +169,14 @@ class CC_EXPORT CompositorFrameReporter { ...@@ -161,6 +169,14 @@ class CC_EXPORT CompositorFrameReporter {
FrameTerminationStatus::kUnknown; FrameTerminationStatus::kUnknown;
const base::flat_set<FrameSequenceTrackerType>* active_trackers_; const base::flat_set<FrameSequenceTrackerType>* active_trackers_;
// Indicates if work on Impl frame is finished.
bool did_finish_impl_frame_ = false;
// Indicates if main frame is aborted after begin.
bool did_abort_main_frame_ = false;
// The time that work on Impl frame is finished. It's only valid if the
// reporter is in a stage other than begin impl frame.
base::TimeTicks impl_frame_finish_time_;
}; };
} // namespace cc } // namespace cc
......
...@@ -59,43 +59,60 @@ void CompositorFrameReportingController::WillBeginImplFrame() { ...@@ -59,43 +59,60 @@ void CompositorFrameReportingController::WillBeginImplFrame() {
std::unique_ptr<CompositorFrameReporter> reporter = std::unique_ptr<CompositorFrameReporter> reporter =
std::make_unique<CompositorFrameReporter>(&active_trackers_, std::make_unique<CompositorFrameReporter>(&active_trackers_,
is_single_threaded_); is_single_threaded_);
reporter->StartStage( reporter->StartStage(StageType::kBeginImplFrameToSendBeginMainFrame,
CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame, begin_time);
begin_time);
reporters_[PipelineStage::kBeginImplFrame] = std::move(reporter); reporters_[PipelineStage::kBeginImplFrame] = std::move(reporter);
} }
void CompositorFrameReportingController::WillBeginMainFrame() { void CompositorFrameReportingController::WillBeginMainFrame() {
DCHECK(reporters_[PipelineStage::kBeginImplFrame]); if (reporters_[PipelineStage::kBeginImplFrame]) {
// We need to use .get() below because operator<< in std::unique_ptr is a // We need to use .get() below because operator<< in std::unique_ptr is a
// C++20 feature. // C++20 feature.
DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(), DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(),
reporters_[PipelineStage::kBeginImplFrame].get()); reporters_[PipelineStage::kBeginImplFrame].get());
reporters_[PipelineStage::kBeginImplFrame]->StartStage( reporters_[PipelineStage::kBeginImplFrame]->StartStage(
CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now()); StageType::kSendBeginMainFrameToCommit, Now());
AdvanceReporterStage(PipelineStage::kBeginImplFrame, AdvanceReporterStage(PipelineStage::kBeginImplFrame,
PipelineStage::kBeginMainFrame); 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() { void CompositorFrameReportingController::BeginMainFrameAborted() {
DCHECK(reporters_[PipelineStage::kBeginMainFrame]); DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
std::unique_ptr<CompositorFrameReporter> aborted_frame_reporter =
std::move(reporters_[PipelineStage::kBeginMainFrame]); auto& begin_main_reporter = reporters_[PipelineStage::kBeginMainFrame];
aborted_frame_reporter->TerminateFrame( begin_main_reporter->OnAbortBeginMainFrame();
CompositorFrameReporter::FrameTerminationStatus::kMainFrameAborted,
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_finish_impl_frame()) {
begin_main_reporter->StartStage(
StageType::kEndActivateToSubmitCompositorFrame, Now());
AdvanceReporterStage(PipelineStage::kBeginMainFrame,
PipelineStage::kActivate);
}
} }
void CompositorFrameReportingController::WillCommit() { void CompositorFrameReportingController::WillCommit() {
DCHECK(reporters_[PipelineStage::kBeginMainFrame]); DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
reporters_[PipelineStage::kBeginMainFrame]->StartStage( reporters_[PipelineStage::kBeginMainFrame]->StartStage(StageType::kCommit,
CompositorFrameReporter::StageType::kCommit, Now()); Now());
} }
void CompositorFrameReportingController::DidCommit() { void CompositorFrameReportingController::DidCommit() {
DCHECK(reporters_[PipelineStage::kBeginMainFrame]); DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
reporters_[PipelineStage::kBeginMainFrame]->StartStage( reporters_[PipelineStage::kBeginMainFrame]->StartStage(
CompositorFrameReporter::StageType::kEndCommitToActivation, Now()); StageType::kEndCommitToActivation, Now());
AdvanceReporterStage(PipelineStage::kBeginMainFrame, PipelineStage::kCommit); AdvanceReporterStage(PipelineStage::kBeginMainFrame, PipelineStage::kCommit);
} }
...@@ -109,8 +126,7 @@ void CompositorFrameReportingController::WillActivate() { ...@@ -109,8 +126,7 @@ void CompositorFrameReportingController::WillActivate() {
DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_); DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_);
if (!reporters_[PipelineStage::kCommit]) if (!reporters_[PipelineStage::kCommit])
return; return;
reporters_[PipelineStage::kCommit]->StartStage( reporters_[PipelineStage::kCommit]->StartStage(StageType::kActivation, Now());
CompositorFrameReporter::StageType::kActivation, Now());
} }
void CompositorFrameReportingController::DidActivate() { void CompositorFrameReportingController::DidActivate() {
...@@ -119,25 +135,57 @@ void CompositorFrameReportingController::DidActivate() { ...@@ -119,25 +135,57 @@ void CompositorFrameReportingController::DidActivate() {
if (!reporters_[PipelineStage::kCommit]) if (!reporters_[PipelineStage::kCommit])
return; return;
reporters_[PipelineStage::kCommit]->StartStage( reporters_[PipelineStage::kCommit]->StartStage(
CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame, StageType::kEndActivateToSubmitCompositorFrame, Now());
Now());
AdvanceReporterStage(PipelineStage::kCommit, PipelineStage::kActivate); AdvanceReporterStage(PipelineStage::kCommit, PipelineStage::kActivate);
} }
void CompositorFrameReportingController::DidSubmitCompositorFrame( void CompositorFrameReportingController::DidSubmitCompositorFrame(
uint32_t frame_token) { 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]) if (!reporters_[PipelineStage::kActivate])
return; return;
std::unique_ptr<CompositorFrameReporter> submitted_reporter = std::unique_ptr<CompositorFrameReporter> submitted_reporter =
std::move(reporters_[PipelineStage::kActivate]); std::move(reporters_[PipelineStage::kActivate]);
submitted_reporter->StartStage( submitted_reporter->StartStage(
CompositorFrameReporter::StageType:: StageType::kSubmitCompositorFrameToPresentationCompositorFrame, Now());
kSubmitCompositorFrameToPresentationCompositorFrame,
Now());
submitted_compositor_frames_.emplace_back(frame_token, submitted_compositor_frames_.emplace_back(frame_token,
std::move(submitted_reporter)); std::move(submitted_reporter));
} }
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( void CompositorFrameReportingController::DidPresentCompositorFrame(
uint32_t frame_token, uint32_t frame_token,
const viz::FrameTimingDetails& details) { const viz::FrameTimingDetails& details) {
......
...@@ -57,6 +57,7 @@ class CC_EXPORT CompositorFrameReportingController { ...@@ -57,6 +57,7 @@ class CC_EXPORT CompositorFrameReportingController {
virtual void WillActivate(); virtual void WillActivate();
virtual void DidActivate(); virtual void DidActivate();
virtual void DidSubmitCompositorFrame(uint32_t frame_token); virtual void DidSubmitCompositorFrame(uint32_t frame_token);
virtual void OnFinishImplFrame();
virtual void DidPresentCompositorFrame( virtual void DidPresentCompositorFrame(
uint32_t frame_token, uint32_t frame_token,
const viz::FrameTimingDetails& details); const viz::FrameTimingDetails& details);
......
...@@ -721,6 +721,8 @@ void CompositorTimingHistory::WillBeginImplFrame( ...@@ -721,6 +721,8 @@ void CompositorTimingHistory::WillBeginImplFrame(
void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) {
if (!needs_redraw) if (!needs_redraw)
SetCompositorDrawingContinuously(false); SetCompositorDrawingContinuously(false);
compositor_frame_reporting_controller_->OnFinishImplFrame();
} }
void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment