Commit 8f5fc49b authored by Xida Chen's avatar Xida Chen Committed by Commit Bot

[Reland] Track the last imp-frame

This is a re-land of:
https://chromium-review.googlesource.com/c/chromium/src/+/2079134

The previous CL had a problem where a tracker may not being terminated.
This CL fixes that and tests are added.

PS#3 is the same as the original CL, so that the diffs can be easily
seen.

Bug: 1055844
Change-Id: I62cffba355980013db8fa392fbb66d0ea74749af
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122242Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Commit-Queue: Xida Chen <xidachen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756018}
parent c7f58a70
......@@ -376,6 +376,7 @@ void FrameSequenceTrackerCollection::StopSequence(
frame_trackers_.erase(type);
tracker->ScheduleTerminate();
removal_trackers_.push_back(std::move(tracker));
DestroyTrackers();
}
void FrameSequenceTrackerCollection::StartCustomSequence(int sequence_id) {
......@@ -436,6 +437,11 @@ void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage(
tracker.second->ReportImplFrameCausedNoDamage(ack);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportImplFrameCausedNoDamage(ack);
// Removal trackers continue to process any frames which they started
// observing.
for (auto& tracker : removal_trackers_)
tracker->ReportImplFrameCausedNoDamage(ack);
}
void FrameSequenceTrackerCollection::NotifyMainFrameCausedNoDamage(
......@@ -466,6 +472,13 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame(
tracker.second->ReportSubmitFrame(frame_token, has_missing_content, ack,
origin_args);
}
// Removal trackers continue to process any frames which they started
// observing.
for (auto& tracker : removal_trackers_) {
tracker->ReportSubmitFrame(frame_token, has_missing_content, ack,
origin_args);
}
}
void FrameSequenceTrackerCollection::NotifyFrameEnd(
......@@ -475,6 +488,12 @@ void FrameSequenceTrackerCollection::NotifyFrameEnd(
tracker.second->ReportFrameEnd(args, main_args);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportFrameEnd(args, main_args);
// Removal trackers continue to process any frames which they started
// observing.
for (auto& tracker : removal_trackers_)
tracker->ReportFrameEnd(args, main_args);
DestroyTrackers();
}
void FrameSequenceTrackerCollection::NotifyFramePresented(
......@@ -514,24 +533,6 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
accumulated_metrics_.erase(key);
}
#if DCHECK_IS_ON()
// Handling the case like b(100)s(150)e(100)b(200)n(200), and then
// StopSequence() is called which put this tracker in removal_trackers_.
// Then P(150). In this case, frame 200 isn't processed yet, because this
// no damage impl frame is considered 'processed' at e(200).
const bool incomplete_frame_had_no_damage =
!tracker->compositor_frame_submitted_ &&
tracker->frame_had_no_compositor_damage_;
if (tracker->is_inside_frame_ && incomplete_frame_had_no_damage)
--metrics->impl_throughput().frames_received;
if (metrics->impl_throughput().frames_received !=
metrics->impl_throughput().frames_processed) {
std::string output = tracker->frame_sequence_trace_.str().substr(
tracker->ignored_trace_char_count_);
NOTREACHED() << output;
}
#endif
if (metrics->HasEnoughDataForReporting())
metrics->ReportMetrics();
if (metrics->HasDataLeftForReporting())
......@@ -539,7 +540,10 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
}
}
// Destroy the trackers that are ready to be terminated.
DestroyTrackers();
}
void FrameSequenceTrackerCollection::DestroyTrackers() {
base::EraseIf(
removal_trackers_,
[](const std::unique_ptr<FrameSequenceTracker>& tracker) {
......@@ -588,6 +592,15 @@ FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting(
return frame_trackers_[type].get();
}
FrameSequenceTracker*
FrameSequenceTrackerCollection::GetRemovalTrackerForTesting(
FrameSequenceTrackerType type) {
for (const auto& tracker : removal_trackers_)
if (tracker->type_ == type)
return tracker.get();
return nullptr;
}
void FrameSequenceTrackerCollection::SetUkmManager(UkmManager* manager) {
DCHECK(frame_trackers_.empty());
if (manager)
......@@ -616,19 +629,12 @@ FrameSequenceTracker::FrameSequenceTracker(
FrameSequenceTracker::~FrameSequenceTracker() = default;
void FrameSequenceTracker::ScheduleTerminate() {
// If the last frame has ended and there is no frame awaiting presentation,
// then it is ready to terminate.
if (!is_inside_frame_ && last_submitted_frame_ == 0)
termination_status_ = TerminationStatus::kReadyForTermination;
else
termination_status_ = TerminationStatus::kScheduledForTermination;
// It could happen that a main/impl frame is generated, but never processed
// (didn't report no damage and didn't submit) when this happens.
if (last_processed_impl_sequence_ < last_started_impl_sequence_) {
DCHECK_GE(impl_throughput().frames_expected,
begin_impl_frame_data_.previous_sequence_delta)
<< TRACKER_DCHECK_MSG;
impl_throughput().frames_expected -=
begin_impl_frame_data_.previous_sequence_delta;
#if DCHECK_IS_ON()
--impl_throughput().frames_received;
#endif
}
}
void FrameSequenceTracker::ReportBeginImplFrame(
......@@ -641,10 +647,9 @@ void FrameSequenceTracker::ReportBeginImplFrame(
TRACKER_TRACE_STREAM << "b(" << args.frame_id.sequence_number << ")";
#if DCHECK_IS_ON()
DCHECK(!is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = true;
#if DCHECK_IS_ON()
if (args.type == viz::BeginFrameArgs::NORMAL)
impl_frames_.insert(args.frame_id);
#endif
......@@ -761,8 +766,8 @@ void FrameSequenceTracker::ReportSubmitFrame(
bool has_missing_content,
const viz::BeginFrameAck& ack,
const viz::BeginFrameArgs& origin_args) {
if (termination_status_ != TerminationStatus::kActive ||
ShouldIgnoreBeginFrameSource(ack.frame_id.source_id) ||
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination);
if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id) ||
ShouldIgnoreSequence(ack.frame_id.sequence_number)) {
ignored_frame_tokens_.insert(frame_token);
return;
......@@ -794,8 +799,11 @@ void FrameSequenceTracker::ReportSubmitFrame(
const bool main_change_had_no_damage =
last_no_main_damage_sequence_ != 0 &&
origin_args.frame_id.sequence_number == last_no_main_damage_sequence_;
const bool origin_args_is_valid = origin_args.frame_id.sequence_number <=
begin_main_frame_data_.previous_sequence;
if (!ShouldIgnoreBeginFrameSource(origin_args.frame_id.source_id)) {
if (!ShouldIgnoreBeginFrameSource(origin_args.frame_id.source_id) &&
origin_args_is_valid) {
if (main_changes_after_sequence_started &&
main_changes_include_new_changes && !main_change_had_no_damage) {
submitted_frame_had_new_main_content_ = true;
......@@ -825,8 +833,7 @@ void FrameSequenceTracker::ReportSubmitFrame(
void FrameSequenceTracker::ReportFrameEnd(
const viz::BeginFrameArgs& args,
const viz::BeginFrameArgs& main_args) {
if (termination_status_ != TerminationStatus::kActive)
return;
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination);
if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
return;
......@@ -843,9 +850,7 @@ void FrameSequenceTracker::ReportFrameEnd(
}
if (should_ignore_sequence) {
#if DCHECK_IS_ON()
is_inside_frame_ = false;
#endif
return;
}
......@@ -879,15 +884,18 @@ void FrameSequenceTracker::ReportFrameEnd(
#endif
begin_impl_frame_data_.previous_sequence = 0;
}
// last_submitted_frame_ == 0 means the last impl frame has been presented.
if (termination_status_ == TerminationStatus::kScheduledForTermination &&
last_submitted_frame_ == 0)
termination_status_ = TerminationStatus::kReadyForTermination;
frame_had_no_compositor_damage_ = false;
compositor_frame_submitted_ = false;
submitted_frame_had_new_main_content_ = false;
last_processed_main_sequence_latency_ = 0;
#if DCHECK_IS_ON()
DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = false;
#endif
DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_)
<< TRACKER_DCHECK_MSG;
......@@ -897,15 +905,18 @@ void FrameSequenceTracker::ReportFrameEnd(
void FrameSequenceTracker::ReportFramePresented(
uint32_t frame_token,
const gfx::PresentationFeedback& feedback) {
// !viz::FrameTokenGT(a, b) is equivalent to b >= a.
const bool frame_token_acks_last_frame =
frame_token == last_submitted_frame_ ||
viz::FrameTokenGT(frame_token, last_submitted_frame_);
!viz::FrameTokenGT(last_submitted_frame_, frame_token);
// Update termination status if this is scheduled for termination, and it is
// not waiting for any frames, or it has received the presentation-feedback
// for the latest frame it is tracking.
//
// We should always wait for an impl frame to end, that is, ReportFrameEnd.
if (termination_status_ == TerminationStatus::kScheduledForTermination &&
(last_submitted_frame_ == 0 || frame_token_acks_last_frame)) {
(last_submitted_frame_ == 0 || frame_token_acks_last_frame) &&
!is_inside_frame_) {
termination_status_ = TerminationStatus::kReadyForTermination;
}
......@@ -920,6 +931,9 @@ void FrameSequenceTracker::ReportFramePresented(
if (ignored_frame_tokens_.contains(frame_token))
return;
base::EraseIf(ignored_frame_tokens_, [frame_token](const uint32_t& token) {
return viz::FrameTokenGT(frame_token, token);
});
uint32_t impl_frames_produced = 0;
uint32_t main_frames_produced = 0;
......@@ -1025,16 +1039,15 @@ void FrameSequenceTracker::ReportFramePresented(
void FrameSequenceTracker::ReportImplFrameCausedNoDamage(
const viz::BeginFrameAck& ack) {
if (termination_status_ != TerminationStatus::kActive)
return;
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination);
if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id))
return;
TRACKER_TRACE_STREAM << "n(" << ack.frame_id.sequence_number << ")";
// It is possible that this is called before a begin-impl-frame has been
// dispatched for this frame-sequence. In such cases, ignore this call.
// This tracker would be scheduled to terminate, and this frame doesn't belong
// to that tracker.
if (ShouldIgnoreSequence(ack.frame_id.sequence_number))
return;
......@@ -1133,13 +1146,18 @@ bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource(
return source_id != begin_impl_frame_data_.previous_source;
}
// This check ensures that when ReportBeginMainFrame, or ReportSubmitFrame, or
// ReportFramePresented is called for a particular arg, the ReportBeginImplFrame
// is been called already.
// This check handles two cases:
// 1. When there is a call to ReportBeginMainFrame, or ReportSubmitFrame, or
// ReportFramePresented, there must be a ReportBeginImplFrame for that sequence.
// Otherwise, the begin_impl_frame_data_.previous_sequence would be 0.
// 2. A tracker is scheduled to terminate, then any new request to handle a new
// impl frame whose sequence_number > begin_impl_frame_data_.previous_sequence
// should be ignored.
// Note that sequence_number < begin_impl_frame_data_.previous_sequence cannot
// happen.
bool FrameSequenceTracker::ShouldIgnoreSequence(
uint64_t sequence_number) const {
return begin_impl_frame_data_.previous_sequence == 0 ||
sequence_number < begin_impl_frame_data_.previous_sequence;
return sequence_number != begin_impl_frame_data_.previous_sequence;
}
std::unique_ptr<base::trace_event::TracedValue>
......@@ -1162,6 +1180,11 @@ bool FrameSequenceTracker::ShouldReportMetricsNow(
}
std::unique_ptr<FrameSequenceMetrics> FrameSequenceTracker::TakeMetrics() {
#if DCHECK_IS_ON()
DCHECK_EQ(impl_throughput().frames_received,
impl_throughput().frames_processed)
<< frame_sequence_trace_.str().substr(ignored_trace_char_count_);
#endif
return std::move(metrics_);
}
......
......@@ -227,6 +227,8 @@ class CC_EXPORT FrameSequenceTrackerCollection {
CustomTrackerResults TakeCustomTrackerResults();
FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type);
FrameSequenceTracker* GetRemovalTrackerForTesting(
FrameSequenceTrackerType type);
void SetUkmManager(UkmManager* manager);
......@@ -234,6 +236,8 @@ class CC_EXPORT FrameSequenceTrackerCollection {
friend class FrameSequenceTrackerTest;
void RecreateTrackers(const viz::BeginFrameArgs& args);
// Destroy the trackers that are ready to be terminated.
void DestroyTrackers();
const bool is_single_threaded_;
// The callsite can use the type to manipulate the tracker.
......@@ -489,9 +493,11 @@ class CC_EXPORT FrameSequenceTracker {
void Advance(base::TimeTicks new_timestamp);
} trace_data_;
#if DCHECK_IS_ON()
// True when an impl-impl is not ended. A tracker is ready for termination
// only when the last impl-frame is ended (ReportFrameEnd).
bool is_inside_frame_ = false;
#if DCHECK_IS_ON()
// This stringstream represents a sequence of frame reporting activities on
// the current tracker. Each letter can be one of the following:
// {'B', 'N', 'b', 'n', 'S', 'P'}, where
......
......@@ -179,6 +179,8 @@ class FrameSequenceTrackerTest : public testing::Test {
case 's': {
auto frame_token = sequence;
if (current_frame == 0)
current_frame = 1;
auto args = CreateBeginFrameArgs(source_id, current_frame);
auto main_args = args;
if (*str == 'S') {
......@@ -266,6 +268,15 @@ class FrameSequenceTrackerTest : public testing::Test {
tracker_->termination_status_ = status;
}
FrameSequenceTracker::TerminationStatus GetTerminationStatus() {
return tracker_->termination_status_;
}
FrameSequenceTracker::TerminationStatus GetTerminationStatusForTracker(
FrameSequenceTracker* tracker) {
return tracker->termination_status_;
}
protected:
uint32_t number_of_frames_checkerboarded() const {
return tracker_->metrics_->frames_checkerboarded();
......@@ -339,16 +350,8 @@ TEST_F(FrameSequenceTrackerTest, TestNotifyFramePresented) {
EXPECT_EQ(NumberOfTrackers(), 3u);
EXPECT_TRUE(TrackerExists(FrameSequenceTrackerType::kMainThreadAnimation));
EXPECT_TRUE(TrackerExists(FrameSequenceTrackerType::kTouchScroll));
ASSERT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_TRUE(
RemovalTrackerExists(0, FrameSequenceTrackerType::kCompositorAnimation));
gfx::PresentationFeedback feedback;
collection_.NotifyFramePresented(1u, feedback);
// NotifyFramePresented should call ReportFramePresented on all the
// |removal_trackers_|, which changes their termination_status_ to
// kReadyForTermination. So at this point, the |removal_trackers_| should be
// empty.
// StopSequence should have destroyed all trackers because there is no frame
// awaiting presentation.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
}
......@@ -535,7 +538,8 @@ TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) {
collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false));
collection_.NotifyFrameEnd(args, args);
EXPECT_EQ(NumberOfTrackers(), 1u);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
// At NotifyFrameEnd, the tracker is removed from removal_tracker_ list.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
}
TEST_F(FrameSequenceTrackerTest, ReportWithoutBeginImplFrame) {
......@@ -780,7 +784,7 @@ TEST_F(FrameSequenceTrackerTest, BeginImplFrameBeforeTerminate) {
EXPECT_EQ(ImplThroughput().frames_expected, 4u);
EXPECT_EQ(ImplThroughput().frames_produced, 1u);
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(ImplThroughput().frames_expected, 1u);
EXPECT_EQ(ImplThroughput().frames_expected, 4u);
EXPECT_EQ(ImplThroughput().frames_produced, 1u);
}
......@@ -1065,28 +1069,637 @@ TEST_F(FrameSequenceTrackerTest, MainThroughputWithHighLatency) {
EXPECT_EQ(MainThroughput().frames_produced, 1u);
}
#if DCHECK_IS_ON()
// These two tests ensures that when present a frame, the frames_received is
// the same as frames_processed. As long as there is no crash, the condition is
// true.
TEST_F(FrameSequenceTrackerTest, FramesProcessedMatch1) {
const char sequence[] = "b(1)n(1)e(1,0)b(2)s(2)e(2,0)b(3)n(3)";
GenerateSequence(sequence);
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame1) {
GenerateSequence("b(1)s(1)e(1,0)b(4)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
SetTerminationStatus(
FrameSequenceTracker::TerminationStatus::kReadyForTermination);
GenerateSequence("P(2)");
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("P(1)");
// There is still one impl-frame not processed not, so the tracker is not yet
// ready for termination.
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
}
TEST_F(FrameSequenceTrackerTest, FramesProcessedMatch2) {
const char sequence[] = "b(1)n(1)e(1,0)b(2)s(2)e(2,0)b(3)s(3)";
GenerateSequence(sequence);
// Following 3 cases are for: b(1)s(1)e(1,0)P(1), and StopSequence can happen
// anywhere after b and before P.
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame2) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("s(1)e(1,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame3) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(1,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame4) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
// Following 2 cases are for: b(1)s(1)P(1), and StopSequence can happen
// anywhere after b and before P. Because there is no e when P happens, the
// tracker is not ready for termination.
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame5) {
GenerateSequence("b(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("s(1)P(1)");
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame6) {
GenerateSequence("b(1)s(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("P(1)");
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
}
// All the following cases are for one complete impl + one incomplete:
// b(1)s(1)e(1,0)xxxxxxxxP(1)
// The 'xxxxx' is an incomplete impl frame that has no damage, it could be
// 1. b(2)n(2)e(2,0)P(1), and StopSequence can happen anywhere after b and
// before P.
// 2. b(2)n(2)P(1), and StopSequence can happen anywhere after b and before P.
// In this case, the tracker is not ready for termination yet because e never
// happens.
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame7) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)b(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("n(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame8) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)b(2)n(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame9) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)b(2)n(2)e(2,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
SetTerminationStatus(
FrameSequenceTracker::TerminationStatus::kReadyForTermination);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame10) {
GenerateSequence("b(1)s(1)e(1,0)b(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("n(2)P(1)");
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame11) {
GenerateSequence("b(1)s(1)e(1,0)b(2)n(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("P(1)");
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
}
// Following tests are for the case where the last impl-frame has no damage.
// Basically b(1)s(1)e(1)P(1)b(2)n(2)e(2). And StopSequence can happen any time
// after b(2).
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame12) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)P(1)b(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("n(2)e(2,0)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame13) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)P(1)b(2)n(2)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(2,0)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame14) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)P(1)b(2)n(2)e(2,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
// The tracker should have been removed from the removal_tracker_ list.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
// Following tests are for the case where the presentation of the first impl
// frame arrives late, and a second impl frame has started, and the tracker is
// scheduled to terminate before the second impl frame starts. Basically:
// 1. b(1)s(1)e(1,0)b(2)s(2)e(2,0)P(1), and StopSequence happens anywhere after
// b(1) and before b(2)
// 2. b(1)s(1)e(1,0)b(2)n(2)e(2,0)P(1), and StopSequence happens anywhere after
// b(1) and before b(2)
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame15) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("s(1)e(1,0)b(2)s(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame16) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(1,0)b(2)s(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame17) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("b(2)s(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
// The second impl-frame has no damage.
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame18) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("s(1)e(1,0)b(2)n(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame19) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(1,0)b(2)n(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame20) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)s(1)e(1,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("b(2)n(2)e(2,0)P(1)");
// Now the |removal_tracker| should have been destroyed.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
std::string metric = "Graphics.Smoothness.FrameSequenceLength.TouchScroll";
// Both impl and slower threads reports 101 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 101), 2);
// The main thread reports 0 frames expected.
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
// Following cases test that no frame needs to be presented, basically:
// b(1)n(1)e(1,0), and StopSequence can happen anytime after b(1).
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame21) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("n(1)e(1,0)");
// Ensure that this tracker is actually removed from the |removal_trackers_|
// before the test terminates.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
// If the tracker is terminated successfully, we should see this UMA.
std::string metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame22) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)n(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
FrameSequenceTracker* removal_tracker =
collection_.GetRemovalTrackerForTesting(
FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(GetTerminationStatusForTracker(removal_tracker),
FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
GenerateSequence("e(1,0)");
// Ensure that this tracker is actually removed from the |removal_trackers_|
// before the test terminates.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
// If the tracker is terminated successfully, we should see this UMA.
std::string metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame23) {
base::HistogramTester histogram_tester;
// Ensure we have enough data to report.
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)n(1)e(1,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
// Ensure that this tracker is actually removed from the |removal_trackers_|
// before the test terminates.
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
// If the tracker is terminated successfully, we should see this UMA.
std::string metric =
"Graphics.Smoothness.PercentDroppedFrames.CompositorThread.TouchScroll";
EXPECT_EQ(histogram_tester.GetBucketCount(metric, 0), 1);
}
// This test ensure that the tracker would terminate at e.
TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame24) {
GenerateSequence("b(1)s(1)P(1)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
GenerateSequence("e(1,0)");
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
}
TEST_F(FrameSequenceTrackerTest, IgnoredFrameTokensRemovedAtPresentation1) {
GenerateSequence("b(5)");
auto args = CreateBeginFrameArgs(/*source_id=*/1u, 1u);
// Ack to an impl frame that doesn't exist in this tracker.
collection_.NotifySubmitFrame(1, /*has_missing_content=*/false,
viz::BeginFrameAck(args, true), args);
EXPECT_EQ(IgnoredFrameTokens().size(), 1u);
args = CreateBeginFrameArgs(1u, 5u);
collection_.NotifySubmitFrame(2, false, viz::BeginFrameAck(args, true), args);
GenerateSequence("e(5,0)b(6)");
// Ack to an impl frame that doesn't exist in this tracker.
args = CreateBeginFrameArgs(1u, 1u);
collection_.NotifySubmitFrame(3, false, viz::BeginFrameAck(args, true), args);
args = CreateBeginFrameArgs(1u, 6u);
collection_.NotifySubmitFrame(4, false, viz::BeginFrameAck(args, true), args);
EXPECT_EQ(IgnoredFrameTokens().size(), 2u);
GenerateSequence("P(2)");
// frame_token = 2 is presented, frame_token = 3 remains in the list.
EXPECT_EQ(IgnoredFrameTokens().size(), 1u);
GenerateSequence("P(4)");
// Now frame_token = 4 is presented, frame_token = 3 should be removed.
EXPECT_TRUE(IgnoredFrameTokens().empty());
}
// Test the case where the frame tokens wraps around the 32-bit max value.
TEST_F(FrameSequenceTrackerTest, IgnoredFrameTokensRemovedAtPresentation2) {
GenerateSequence("b(5)");
auto args = CreateBeginFrameArgs(1u, 1u);
// Ack to an impl frame that doesn't exist in this tracker.
collection_.NotifySubmitFrame(UINT32_MAX, /*has_missing_content=*/false,
viz::BeginFrameAck(args, true), args);
EXPECT_EQ(IgnoredFrameTokens().size(), 1u);
args = CreateBeginFrameArgs(1u, 5u);
collection_.NotifySubmitFrame(1, false, viz::BeginFrameAck(args, true), args);
GenerateSequence("e(5,0)P(1)");
EXPECT_TRUE(IgnoredFrameTokens().empty());
}
#endif
TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage1) {
const char sequence[] =
......@@ -1120,8 +1733,7 @@ TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage3) {
TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage4) {
const char sequence[] =
"b(9)B(0,9)n(9)Re(9,0)E(9)b(11)B(0,11)n(11)e(11,9)b(12)E(11)B(11,12)s(1)"
"S(11)"
"e(12,11)b(13)E(12)s(2)S(12)";
"S(11)e(12,11)b(13)E(12)s(2)S(12)";
GenerateSequence(sequence);
EXPECT_EQ(ImplThroughput().frames_expected, 2u);
EXPECT_EQ(MainThroughput().frames_expected, 2u);
......
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