Commit 14f4f84a authored by Xida Chen's avatar Xida Chen Committed by Commit Bot

Revert "[throughput] Track last frame"

This reverts commit fd2cb104.

Reason for revert: causing crash

Original change's description:
> [throughput] Track last frame
> 
> It could happen that after a BeginImpl(Main)Frame is reported, a tracker
> is scheduled to terminate. In this case, any subsequent handling of
> that impl(main)-frame will be lost. In other words, we completely lost
> track of the last frame.
> 
> This CL fixes the impl frame, the fix for main frame comes later because
> this CL is already big.
> 
> Bug: 1055844
> Change-Id: I1cc65e9a5d973ecb67c83105be03f7bc08139dae
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2079134
> Commit-Queue: Xida Chen <xidachen@chromium.org>
> Reviewed-by: Robert Flack <flackr@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#752529}

TBR=flackr@chromium.org,xidachen@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 1055844
Change-Id: I5c96139dd4eb8bd38d2133a1b9d8d4d69bacff18
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2122041Reviewed-by: default avatarXida Chen <xidachen@chromium.org>
Commit-Queue: Xida Chen <xidachen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#753621}
parent d0d4d250
...@@ -334,7 +334,6 @@ void FrameSequenceTrackerCollection::StopSequence( ...@@ -334,7 +334,6 @@ void FrameSequenceTrackerCollection::StopSequence(
frame_trackers_.erase(type); frame_trackers_.erase(type);
tracker->ScheduleTerminate(); tracker->ScheduleTerminate();
removal_trackers_.push_back(std::move(tracker)); removal_trackers_.push_back(std::move(tracker));
DestroyTrackers();
} }
void FrameSequenceTrackerCollection::ClearAll() { void FrameSequenceTrackerCollection::ClearAll() {
...@@ -363,19 +362,16 @@ void FrameSequenceTrackerCollection::NotifyMainFrameProcessed( ...@@ -363,19 +362,16 @@ void FrameSequenceTrackerCollection::NotifyMainFrameProcessed(
void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage( void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage(
const viz::BeginFrameAck& ack) { const viz::BeginFrameAck& ack) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_) {
tracker.second->ReportImplFrameCausedNoDamage(ack); 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( void FrameSequenceTrackerCollection::NotifyMainFrameCausedNoDamage(
const viz::BeginFrameArgs& args) { const viz::BeginFrameArgs& args) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_) {
tracker.second->ReportMainFrameCausedNoDamage(args); tracker.second->ReportMainFrameCausedNoDamage(args);
}
} }
void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() { void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() {
...@@ -392,27 +388,14 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame( ...@@ -392,27 +388,14 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame(
tracker.second->ReportSubmitFrame(frame_token, has_missing_content, ack, tracker.second->ReportSubmitFrame(frame_token, has_missing_content, ack,
origin_args); 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( void FrameSequenceTrackerCollection::NotifyFrameEnd(
const viz::BeginFrameArgs& args, const viz::BeginFrameArgs& args,
const viz::BeginFrameArgs& main_args) { const viz::BeginFrameArgs& main_args) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_) {
tracker.second->ReportFrameEnd(args, main_args); 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( void FrameSequenceTrackerCollection::NotifyFramePresented(
...@@ -438,6 +421,24 @@ void FrameSequenceTrackerCollection::NotifyFramePresented( ...@@ -438,6 +421,24 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
accumulated_metrics_.erase(tracker->type()); accumulated_metrics_.erase(tracker->type());
} }
#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()) if (metrics->HasEnoughDataForReporting())
metrics->ReportMetrics(); metrics->ReportMetrics();
if (metrics->HasDataLeftForReporting()) if (metrics->HasDataLeftForReporting())
...@@ -445,10 +446,7 @@ void FrameSequenceTrackerCollection::NotifyFramePresented( ...@@ -445,10 +446,7 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
} }
} }
DestroyTrackers(); // Destroy the trackers that are ready to be terminated.
}
void FrameSequenceTrackerCollection::DestroyTrackers() {
base::EraseIf( base::EraseIf(
removal_trackers_, removal_trackers_,
[](const std::unique_ptr<FrameSequenceTracker>& tracker) { [](const std::unique_ptr<FrameSequenceTracker>& tracker) {
...@@ -492,15 +490,6 @@ FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting( ...@@ -492,15 +490,6 @@ FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting(
return frame_trackers_[type].get(); 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) { void FrameSequenceTrackerCollection::SetUkmManager(UkmManager* manager) {
DCHECK(frame_trackers_.empty()); DCHECK(frame_trackers_.empty());
if (manager) if (manager)
...@@ -526,12 +515,19 @@ FrameSequenceTracker::~FrameSequenceTracker() { ...@@ -526,12 +515,19 @@ FrameSequenceTracker::~FrameSequenceTracker() {
} }
void FrameSequenceTracker::ScheduleTerminate() { 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; 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::ReportMetricsForTesting() { void FrameSequenceTracker::ReportMetricsForTesting() {
...@@ -548,9 +544,10 @@ void FrameSequenceTracker::ReportBeginImplFrame( ...@@ -548,9 +544,10 @@ void FrameSequenceTracker::ReportBeginImplFrame(
TRACKER_TRACE_STREAM << "b(" << args.frame_id.sequence_number << ")"; TRACKER_TRACE_STREAM << "b(" << args.frame_id.sequence_number << ")";
#if DCHECK_IS_ON()
DCHECK(!is_inside_frame_) << TRACKER_DCHECK_MSG; DCHECK(!is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = true; is_inside_frame_ = true;
#if DCHECK_IS_ON()
if (args.type == viz::BeginFrameArgs::NORMAL) if (args.type == viz::BeginFrameArgs::NORMAL)
impl_frames_.insert(args.frame_id); impl_frames_.insert(args.frame_id);
#endif #endif
...@@ -667,8 +664,8 @@ void FrameSequenceTracker::ReportSubmitFrame( ...@@ -667,8 +664,8 @@ void FrameSequenceTracker::ReportSubmitFrame(
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) {
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination); if (termination_status_ != TerminationStatus::kActive ||
if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id) || ShouldIgnoreBeginFrameSource(ack.frame_id.source_id) ||
ShouldIgnoreSequence(ack.frame_id.sequence_number)) { ShouldIgnoreSequence(ack.frame_id.sequence_number)) {
ignored_frame_tokens_.insert(frame_token); ignored_frame_tokens_.insert(frame_token);
return; return;
...@@ -700,12 +697,10 @@ void FrameSequenceTracker::ReportSubmitFrame( ...@@ -700,12 +697,10 @@ void FrameSequenceTracker::ReportSubmitFrame(
const bool main_change_had_no_damage = const bool main_change_had_no_damage =
last_no_main_damage_sequence_ != 0 && last_no_main_damage_sequence_ != 0 &&
origin_args.frame_id.sequence_number == last_no_main_damage_sequence_; 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) &&
main_changes_after_sequence_started && main_changes_include_new_changes && main_changes_after_sequence_started && main_changes_include_new_changes &&
!main_change_had_no_damage && origin_args_is_valid) { !main_change_had_no_damage) {
submitted_frame_had_new_main_content_ = true; submitted_frame_had_new_main_content_ = true;
TRACKER_TRACE_STREAM << "S(" << origin_args.frame_id.sequence_number << ")"; TRACKER_TRACE_STREAM << "S(" << origin_args.frame_id.sequence_number << ")";
...@@ -723,7 +718,8 @@ void FrameSequenceTracker::ReportSubmitFrame( ...@@ -723,7 +718,8 @@ void FrameSequenceTracker::ReportSubmitFrame(
void FrameSequenceTracker::ReportFrameEnd( void FrameSequenceTracker::ReportFrameEnd(
const viz::BeginFrameArgs& args, const viz::BeginFrameArgs& args,
const viz::BeginFrameArgs& main_args) { const viz::BeginFrameArgs& main_args) {
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination); if (termination_status_ != TerminationStatus::kActive)
return;
if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id)) if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
return; return;
...@@ -740,7 +736,9 @@ void FrameSequenceTracker::ReportFrameEnd( ...@@ -740,7 +736,9 @@ void FrameSequenceTracker::ReportFrameEnd(
} }
if (should_ignore_sequence) { if (should_ignore_sequence) {
#if DCHECK_IS_ON()
is_inside_frame_ = false; is_inside_frame_ = false;
#endif
return; return;
} }
...@@ -773,19 +771,16 @@ void FrameSequenceTracker::ReportFrameEnd( ...@@ -773,19 +771,16 @@ void FrameSequenceTracker::ReportFrameEnd(
NOTREACHED() << TRACKER_DCHECK_MSG; NOTREACHED() << TRACKER_DCHECK_MSG;
#endif #endif
begin_impl_frame_data_.previous_sequence = 0; 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; frame_had_no_compositor_damage_ = false;
compositor_frame_submitted_ = false; compositor_frame_submitted_ = false;
submitted_frame_had_new_main_content_ = false; submitted_frame_had_new_main_content_ = false;
last_processed_main_sequence_latency_ = 0; last_processed_main_sequence_latency_ = 0;
#if DCHECK_IS_ON()
DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG; DCHECK(is_inside_frame_) << TRACKER_DCHECK_MSG;
is_inside_frame_ = false; is_inside_frame_ = false;
#endif
DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_) DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_)
<< TRACKER_DCHECK_MSG; << TRACKER_DCHECK_MSG;
...@@ -795,18 +790,15 @@ void FrameSequenceTracker::ReportFrameEnd( ...@@ -795,18 +790,15 @@ void FrameSequenceTracker::ReportFrameEnd(
void FrameSequenceTracker::ReportFramePresented( void FrameSequenceTracker::ReportFramePresented(
uint32_t frame_token, uint32_t frame_token,
const gfx::PresentationFeedback& feedback) { const gfx::PresentationFeedback& feedback) {
// !viz::FrameTokenGT(a, b) is equivalent to b >= a.
const bool frame_token_acks_last_frame = const bool frame_token_acks_last_frame =
!viz::FrameTokenGT(last_submitted_frame_, frame_token); frame_token == last_submitted_frame_ ||
viz::FrameTokenGT(frame_token, last_submitted_frame_);
// Update termination status if this is scheduled for termination, and it is // Update termination status if this is scheduled for termination, and it is
// not waiting for any frames, or it has received the presentation-feedback // not waiting for any frames, or it has received the presentation-feedback
// for the latest frame it is tracking. // 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 && 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; termination_status_ = TerminationStatus::kReadyForTermination;
} }
...@@ -886,15 +878,16 @@ void FrameSequenceTracker::ReportFramePresented( ...@@ -886,15 +878,16 @@ void FrameSequenceTracker::ReportFramePresented(
void FrameSequenceTracker::ReportImplFrameCausedNoDamage( void FrameSequenceTracker::ReportImplFrameCausedNoDamage(
const viz::BeginFrameAck& ack) { const viz::BeginFrameAck& ack) {
DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination); if (termination_status_ != TerminationStatus::kActive)
return;
if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id)) if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id))
return; return;
TRACKER_TRACE_STREAM << "n(" << ack.frame_id.sequence_number << ")"; TRACKER_TRACE_STREAM << "n(" << ack.frame_id.sequence_number << ")";
// This tracker would be scheduled to terminate, and this frame doesn't belong // It is possible that this is called before a begin-impl-frame has been
// to that tracker. // dispatched for this frame-sequence. In such cases, ignore this call.
if (ShouldIgnoreSequence(ack.frame_id.sequence_number)) if (ShouldIgnoreSequence(ack.frame_id.sequence_number))
return; return;
...@@ -988,18 +981,13 @@ bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource( ...@@ -988,18 +981,13 @@ bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource(
return source_id != begin_impl_frame_data_.previous_source; return source_id != begin_impl_frame_data_.previous_source;
} }
// This check handles two cases: // This check ensures that when ReportBeginMainFrame, or ReportSubmitFrame, or
// 1. When there is a call to ReportBeginMainFrame, or ReportSubmitFrame, or // ReportFramePresented is called for a particular arg, the ReportBeginImplFrame
// ReportFramePresented, there must be a ReportBeginImplFrame for that sequence. // is been called already.
// 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( bool FrameSequenceTracker::ShouldIgnoreSequence(
uint64_t sequence_number) const { uint64_t sequence_number) const {
return sequence_number != begin_impl_frame_data_.previous_sequence; return begin_impl_frame_data_.previous_sequence == 0 ||
sequence_number < begin_impl_frame_data_.previous_sequence;
} }
std::unique_ptr<base::trace_event::TracedValue> std::unique_ptr<base::trace_event::TracedValue>
...@@ -1022,11 +1010,6 @@ bool FrameSequenceTracker::ShouldReportMetricsNow( ...@@ -1022,11 +1010,6 @@ bool FrameSequenceTracker::ShouldReportMetricsNow(
} }
std::unique_ptr<FrameSequenceMetrics> FrameSequenceTracker::TakeMetrics() { 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_); return std::move(metrics_);
} }
......
...@@ -192,8 +192,6 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -192,8 +192,6 @@ class CC_EXPORT FrameSequenceTrackerCollection {
ActiveFrameSequenceTrackers FrameSequenceTrackerActiveTypes(); ActiveFrameSequenceTrackers FrameSequenceTrackerActiveTypes();
FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type); FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type);
FrameSequenceTracker* GetRemovalTrackerForTesting(
FrameSequenceTrackerType type);
void SetUkmManager(UkmManager* manager); void SetUkmManager(UkmManager* manager);
...@@ -201,8 +199,6 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -201,8 +199,6 @@ class CC_EXPORT FrameSequenceTrackerCollection {
friend class FrameSequenceTrackerTest; friend class FrameSequenceTrackerTest;
void RecreateTrackers(const viz::BeginFrameArgs& args); void RecreateTrackers(const viz::BeginFrameArgs& args);
// Destroy the trackers that are ready to be terminated.
void DestroyTrackers();
const bool is_single_threaded_; const bool is_single_threaded_;
// The callsite can use the type to manipulate the tracker. // The callsite can use the type to manipulate the tracker.
...@@ -231,9 +227,9 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -231,9 +227,9 @@ class CC_EXPORT FrameSequenceTrackerCollection {
class CC_EXPORT FrameSequenceTracker { class CC_EXPORT FrameSequenceTracker {
public: public:
enum class TerminationStatus { enum class TerminationStatus {
kActive = 0, kActive,
kScheduledForTermination = 1, kScheduledForTermination,
kReadyForTermination = 2, kReadyForTermination,
}; };
static const char* GetFrameSequenceTrackerTypeName( static const char* GetFrameSequenceTrackerTypeName(
...@@ -439,11 +435,9 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -439,11 +435,9 @@ class CC_EXPORT FrameSequenceTracker {
void Advance(base::TimeTicks new_timestamp); void Advance(base::TimeTicks new_timestamp);
} trace_data_; } trace_data_;
// True when an impl-impl is not ended. A tracker is ready for termination #if DCHECK_IS_ON()
// only when the last impl-frame is ended (ReportFrameEnd).
bool is_inside_frame_ = false; bool is_inside_frame_ = false;
#if DCHECK_IS_ON()
// 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
......
...@@ -119,9 +119,17 @@ class FrameSequenceTrackerTest : public testing::Test { ...@@ -119,9 +119,17 @@ class FrameSequenceTrackerTest : public testing::Test {
FrameSequenceTrackerType::kMainThreadAnimation)); FrameSequenceTrackerType::kMainThreadAnimation));
EXPECT_TRUE(collection_.frame_trackers_.contains( EXPECT_TRUE(collection_.frame_trackers_.contains(
FrameSequenceTrackerType::kTouchScroll)); FrameSequenceTrackerType::kTouchScroll));
// StopSequence should have destroyed all trackers because there is no frame ASSERT_EQ(collection_.removal_trackers_.size(), 1u);
// awaiting presentation. EXPECT_EQ(collection_.removal_trackers_[0]->type_,
ASSERT_EQ(collection_.removal_trackers_.size(), 0u); 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.
EXPECT_TRUE(collection_.removal_trackers_.empty());
} }
void ReportMetricsTest() { void ReportMetricsTest() {
...@@ -255,8 +263,6 @@ class FrameSequenceTrackerTest : public testing::Test { ...@@ -255,8 +263,6 @@ class FrameSequenceTrackerTest : public testing::Test {
case 's': { case 's': {
auto frame_token = sequence; auto frame_token = sequence;
if (current_frame == 0)
current_frame = 1;
auto args = CreateBeginFrameArgs(source_id, current_frame); auto args = CreateBeginFrameArgs(source_id, current_frame);
auto main_args = args; auto main_args = args;
if (*str == 'S') { if (*str == 'S') {
...@@ -338,15 +344,6 @@ class FrameSequenceTrackerTest : public testing::Test { ...@@ -338,15 +344,6 @@ class FrameSequenceTrackerTest : public testing::Test {
tracker_->termination_status_ = status; tracker_->termination_status_ = status;
} }
FrameSequenceTracker::TerminationStatus GetTerminationStatus() {
return tracker_->termination_status_;
}
FrameSequenceTracker::TerminationStatus GetTerminationStatusForTracker(
FrameSequenceTracker* tracker) {
return tracker->termination_status_;
}
protected: protected:
uint32_t number_of_frames_checkerboarded() const { uint32_t number_of_frames_checkerboarded() const {
return tracker_->metrics_->frames_checkerboarded(); return tracker_->metrics_->frames_checkerboarded();
...@@ -539,8 +536,7 @@ TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) { ...@@ -539,8 +536,7 @@ TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) {
collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false)); collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false));
collection_.NotifyFrameEnd(args, args); collection_.NotifyFrameEnd(args, args);
EXPECT_EQ(NumberOfTrackers(), 1u); EXPECT_EQ(NumberOfTrackers(), 1u);
// At NotifyFrameEnd, the tracker is removed from removal_tracker_ list. EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
} }
TEST_F(FrameSequenceTrackerTest, ReportWithoutBeginImplFrame) { TEST_F(FrameSequenceTrackerTest, ReportWithoutBeginImplFrame) {
...@@ -779,6 +775,16 @@ TEST_F(FrameSequenceTrackerTest, SequenceStateResetsDuringFrame) { ...@@ -779,6 +775,16 @@ TEST_F(FrameSequenceTrackerTest, SequenceStateResetsDuringFrame) {
EXPECT_EQ(MainThroughput().frames_produced, 0u); EXPECT_EQ(MainThroughput().frames_produced, 0u);
} }
TEST_F(FrameSequenceTrackerTest, BeginImplFrameBeforeTerminate) {
const char sequence[] = "b(1)s(1)e(1,0)b(4)P(1)";
GenerateSequence(sequence);
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_produced, 1u);
}
// b(2417)B(0,2417)E(2417)n(2417)N(2417,2417) // b(2417)B(0,2417)E(2417)n(2417)N(2417,2417)
TEST_F(FrameSequenceTrackerTest, SequenceNumberReset) { TEST_F(FrameSequenceTrackerTest, SequenceNumberReset) {
const char sequence[] = const char sequence[] =
...@@ -797,589 +803,28 @@ TEST_F(FrameSequenceTrackerTest, MainThroughputWithHighLatency) { ...@@ -797,589 +803,28 @@ TEST_F(FrameSequenceTrackerTest, MainThroughputWithHighLatency) {
EXPECT_EQ(MainThroughput().frames_produced, 1u); EXPECT_EQ(MainThroughput().frames_produced, 1u);
} }
TEST_F(FrameSequenceTrackerTest, ImplFramesProcessedMatch1) { #if DCHECK_IS_ON()
GenerateSequence("b(1)s(1)e(1,0)b(4)"); // These two tests ensures that when present a frame, the frames_received is
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll); // the same as frames_processed. As long as there is no crash, the condition is
EXPECT_EQ(NumberOfRemovalTrackers(), 1u); // true.
FrameSequenceTracker* removal_tracker = TEST_F(FrameSequenceTrackerTest, FramesProcessedMatch1) {
collection_.GetRemovalTrackerForTesting( const char sequence[] = "b(1)n(1)e(1,0)b(2)s(2)e(2,0)b(3)n(3)";
FrameSequenceTrackerType::kTouchScroll); GenerateSequence(sequence);
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);
}
// 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, ImplFramesProcessedMatch2) {
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, ImplFramesProcessedMatch3) {
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, ImplFramesProcessedMatch4) {
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, ImplFramesProcessedMatch5) {
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, ImplFramesProcessedMatch6) {
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, ImplFramesProcessedMatch7) {
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, ImplFramesProcessedMatch8) {
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, ImplFramesProcessedMatch9) {
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);
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, ImplFramesProcessedMatch10) {
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, ImplFramesProcessedMatch11) {
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, ImplFramesProcessedMatch12) {
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, ImplFramesProcessedMatch13) {
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, ImplFramesProcessedMatch14) {
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, ImplFramesProcessedMatch15) {
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, ImplFramesProcessedMatch16) {
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, ImplFramesProcessedMatch17) {
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, ImplFramesProcessedMatch18) {
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, ImplFramesProcessedMatch19) {
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, ImplFramesProcessedMatch20) {
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, ImplFramesProcessedMatch21) {
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, ImplFramesProcessedMatch22) {
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); collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
EXPECT_EQ(NumberOfRemovalTrackers(), 1u); SetTerminationStatus(
FrameSequenceTracker* removal_tracker = FrameSequenceTracker::TerminationStatus::kReadyForTermination);
collection_.GetRemovalTrackerForTesting( GenerateSequence("P(2)");
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, ImplFramesProcessedMatch23) { TEST_F(FrameSequenceTrackerTest, FramesProcessedMatch2) {
base::HistogramTester histogram_tester; const char sequence[] = "b(1)n(1)e(1,0)b(2)s(2)e(2,0)b(3)s(3)";
// Ensure we have enough data to report. GenerateSequence(sequence);
ImplThroughput().frames_expected = 100u;
ImplThroughput().frames_produced = 100u;
GenerateSequence("b(1)n(1)e(1,0)");
collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll); collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
// Ensure that this tracker is actually removed from the |removal_trackers_| SetTerminationStatus(
// before the test terminates. FrameSequenceTracker::TerminationStatus::kReadyForTermination);
EXPECT_EQ(NumberOfRemovalTrackers(), 0u); GenerateSequence("P(2)");
// 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);
} }
#endif
TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage1) { TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage1) {
const char sequence[] = const char sequence[] =
...@@ -1413,7 +858,8 @@ TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage3) { ...@@ -1413,7 +858,8 @@ TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage3) {
TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage4) { TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage4) {
const char sequence[] = 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)" "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); GenerateSequence(sequence);
EXPECT_EQ(ImplThroughput().frames_expected, 2u); EXPECT_EQ(ImplThroughput().frames_expected, 2u);
EXPECT_EQ(MainThroughput().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