Commit 7fe10ea9 authored by Sadrul Habib Chowdhury's avatar Sadrul Habib Chowdhury Committed by Commit Bot

[cc/metrics] Some debug checks in FrameSequenceTracker.

Explicitly notify the FrameSequenceTracker instances when handling a
frame terminates. This is used to validate that the expected sequence
of calls happen correctly, e.g. a new frame does not start before the
earlier frame has completely been processed.

BUG=1021963

Change-Id: I9465148c7478545723e2b3657fdd9b49cdc79d3d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1902069
Commit-Queue: Sadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#723652}
parent 7fb377bd
...@@ -298,6 +298,13 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame( ...@@ -298,6 +298,13 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame(
} }
} }
void FrameSequenceTrackerCollection::NotifyFrameEnd(
const viz::BeginFrameArgs& args) {
for (auto& tracker : frame_trackers_) {
tracker.second->ReportFrameEnd(args);
}
}
void FrameSequenceTrackerCollection::NotifyFramePresented( void FrameSequenceTrackerCollection::NotifyFramePresented(
uint32_t frame_token, uint32_t frame_token,
const gfx::PresentationFeedback& feedback) { const gfx::PresentationFeedback& feedback) {
...@@ -395,12 +402,16 @@ void FrameSequenceTracker::ReportBeginImplFrame( ...@@ -395,12 +402,16 @@ void FrameSequenceTracker::ReportBeginImplFrame(
if (ShouldIgnoreBeginFrameSource(args.source_id)) if (ShouldIgnoreBeginFrameSource(args.source_id))
return; return;
#if DCHECK_IS_ON()
DCHECK(!is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = true;
#endif
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
if (args.type == viz::BeginFrameArgs::NORMAL) if (args.type == viz::BeginFrameArgs::NORMAL)
impl_frames_.insert(std::make_pair(args.source_id, args.sequence_number)); impl_frames_.insert(std::make_pair(args.source_id, args.sequence_number));
#endif #endif
TRACKER_TRACE_STREAM << 'b'; TRACKER_TRACE_STREAM << "b(" << args.sequence_number << ")";
UpdateTrackedFrameData(&begin_impl_frame_data_, args.source_id, UpdateTrackedFrameData(&begin_impl_frame_data_, args.source_id,
args.sequence_number); args.sequence_number);
impl_throughput().frames_expected += impl_throughput().frames_expected +=
...@@ -451,6 +462,9 @@ void FrameSequenceTracker::ReportSubmitFrame( ...@@ -451,6 +462,9 @@ void FrameSequenceTracker::ReportSubmitFrame(
return; return;
} }
#if DCHECK_IS_ON()
DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG;
#endif
if (first_submitted_frame_ == 0) if (first_submitted_frame_ == 0)
first_submitted_frame_ = frame_token; first_submitted_frame_ = frame_token;
last_submitted_frame_ = frame_token; last_submitted_frame_ = frame_token;
...@@ -474,6 +488,25 @@ void FrameSequenceTracker::ReportSubmitFrame( ...@@ -474,6 +488,25 @@ void FrameSequenceTracker::ReportSubmitFrame(
} }
} }
void FrameSequenceTracker::ReportFrameEnd(const viz::BeginFrameArgs& args) {
#if DCHECK_IS_ON()
if (termination_status_ != TerminationStatus::kActive)
return;
if (ShouldIgnoreBeginFrameSource(args.source_id))
return;
if (ShouldIgnoreSequence(args.sequence_number)) {
is_inside_frame_ = false;
return;
}
TRACKER_TRACE_STREAM << "e(" << args.sequence_number << ")";
DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = false;
#endif
}
void FrameSequenceTracker::ReportFramePresented( void FrameSequenceTracker::ReportFramePresented(
uint32_t frame_token, uint32_t frame_token,
const gfx::PresentationFeedback& feedback) { const gfx::PresentationFeedback& feedback) {
......
...@@ -154,6 +154,7 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -154,6 +154,7 @@ class CC_EXPORT FrameSequenceTrackerCollection {
bool has_missing_content, bool has_missing_content,
const viz::BeginFrameAck& ack, const viz::BeginFrameAck& ack,
const viz::BeginFrameArgs& origin_args); const viz::BeginFrameArgs& origin_args);
void NotifyFrameEnd(const viz::BeginFrameArgs& args);
// Note that this notifies the trackers of the presentation-feedbacks, and // Note that this notifies the trackers of the presentation-feedbacks, and
// destroys any tracker that had been scheduled for destruction (using // destroys any tracker that had been scheduled for destruction (using
...@@ -238,6 +239,8 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -238,6 +239,8 @@ class CC_EXPORT FrameSequenceTracker {
const viz::BeginFrameAck& ack, const viz::BeginFrameAck& ack,
const viz::BeginFrameArgs& origin_args); const viz::BeginFrameArgs& origin_args);
void ReportFrameEnd(const viz::BeginFrameArgs& args);
// Notifies the tracker of the presentation-feedback of a previously submitted // Notifies the tracker of the presentation-feedback of a previously submitted
// CompositorFrame with |frame_token|. // CompositorFrame with |frame_token|.
void ReportFramePresented(uint32_t frame_token, void ReportFramePresented(uint32_t frame_token,
...@@ -374,6 +377,8 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -374,6 +377,8 @@ class CC_EXPORT FrameSequenceTracker {
const base::TimeDelta time_delta_to_report_ = base::TimeDelta::FromSeconds(5); const base::TimeDelta time_delta_to_report_ = base::TimeDelta::FromSeconds(5);
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
bool is_inside_frame_ = false;
// This stringstream represents a sequence of frame reporting activities on // This stringstream represents a sequence of frame reporting activities on
// the current tracker. Each letter can be one of the following: // the current tracker. Each letter can be one of the following:
// {'B', 'N', 'b', 'n', 'S', 'P'}, where // {'B', 'N', 'b', 'n', 'S', 'P'}, where
......
...@@ -65,11 +65,13 @@ class FrameSequenceTrackerTest : public testing::Test { ...@@ -65,11 +65,13 @@ class FrameSequenceTrackerTest : public testing::Test {
uint32_t frame_token = NextFrameToken(); uint32_t frame_token = NextFrameToken();
collection_.NotifySubmitFrame(frame_token, has_missing_content, collection_.NotifySubmitFrame(frame_token, has_missing_content,
viz::BeginFrameAck(args, true), args); viz::BeginFrameAck(args, true), args);
collection_.NotifyFrameEnd(args);
return frame_token; return frame_token;
} else { } else {
collection_.NotifyImplFrameCausedNoDamage( collection_.NotifyImplFrameCausedNoDamage(
viz::BeginFrameAck(args, false)); viz::BeginFrameAck(args, false));
collection_.NotifyMainFrameCausedNoDamage(args); collection_.NotifyMainFrameCausedNoDamage(args);
collection_.NotifyFrameEnd(args);
} }
return 0; return 0;
} }
......
...@@ -2310,9 +2310,16 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { ...@@ -2310,9 +2310,16 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
} }
#endif #endif
frame_trackers_.NotifySubmitFrame( // In some cases (e.g. for android-webviews), the frame-submission happens
compositor_frame.metadata.frame_token, frame->has_missing_content, // outside of begin-impl frame pipeline. Avoid notifying the trackers in such
frame->begin_frame_ack, frame->origin_begin_main_frame_args); // cases.
if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
frame_trackers_.NotifySubmitFrame(
compositor_frame.metadata.frame_token, frame->has_missing_content,
frame->begin_frame_ack, frame->origin_begin_main_frame_args);
}
if (!mutator_host_->NextFrameHasPendingRAF()) if (!mutator_host_->NextFrameHasPendingRAF())
frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF); frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF);
...@@ -2725,6 +2732,7 @@ void LayerTreeHostImpl::DidFinishImplFrame() { ...@@ -2725,6 +2732,7 @@ void LayerTreeHostImpl::DidFinishImplFrame() {
frame_trackers_.NotifyMainFrameCausedNoDamage( frame_trackers_.NotifyMainFrameCausedNoDamage(
current_begin_frame_tracker_.Current()); current_begin_frame_tracker_.Current());
} }
frame_trackers_.NotifyFrameEnd(current_begin_frame_tracker_.Current());
impl_thread_phase_ = ImplThreadPhase::IDLE; impl_thread_phase_ = ImplThreadPhase::IDLE;
current_begin_frame_tracker_.Finish(); current_begin_frame_tracker_.Finish();
} }
......
...@@ -207,6 +207,10 @@ void VideoFrameSubmitter::OnBeginFrame( ...@@ -207,6 +207,10 @@ void VideoFrameSubmitter::OnBeginFrame(
frame_trackers_.NotifyBeginImplFrame(args); frame_trackers_.NotifyBeginImplFrame(args);
base::ScopedClosureRunner end_frame(
base::BindOnce(&cc::FrameSequenceTrackerCollection::NotifyFrameEnd,
base::Unretained(&frame_trackers_), args));
// Don't call UpdateCurrentFrame() for MISSED BeginFrames. Also don't call it // Don't call UpdateCurrentFrame() for MISSED BeginFrames. Also don't call it
// after StopRendering() has been called (forbidden by API contract). // after StopRendering() has been called (forbidden by API contract).
viz::BeginFrameAck current_begin_frame_ack(args, false); viz::BeginFrameAck current_begin_frame_ack(args, false);
......
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