Commit ab73cc04 authored by Xiyuan Xia's avatar Xiyuan Xia Committed by Commit Bot

Add kCustom type FrameSequenceTracker

- Add FrameSequenceTrackerType::kCustom;
- Add FrameSequenceTrackerCollection::StartCustomSequence to create
  a kCustom typed tracker to represent a sequence;
- Add FrameSequenceTrackerCollection::StopCustomSequence to schedule
  termination of a tracker for a sequence;
- Data collected by custom trackers are reported via the return
  value of FrameSequenceTrackerCollection::TakeCustomTrackerResults;

Bug: 1021774
Change-Id: I62d9c2eb833e1d40e01b3b452d515ce361233a64
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2007937
Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#754680}
parent 1808574c
...@@ -53,6 +53,8 @@ const char* FrameSequenceTracker::GetFrameSequenceTrackerTypeName( ...@@ -53,6 +53,8 @@ const char* FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
return "WheelScroll"; return "WheelScroll";
case FrameSequenceTrackerType::kScrollbarScroll: case FrameSequenceTrackerType::kScrollbarScroll:
return "ScrollbarScroll"; return "ScrollbarScroll";
case FrameSequenceTrackerType::kCustom:
return "Custom";
case FrameSequenceTrackerType::kMaxType: case FrameSequenceTrackerType::kMaxType:
return ""; return "";
} }
...@@ -178,6 +180,7 @@ FrameSequenceMetrics::ThreadType FrameSequenceMetrics::GetEffectiveThread() ...@@ -178,6 +180,7 @@ FrameSequenceMetrics::ThreadType FrameSequenceMetrics::GetEffectiveThread()
case FrameSequenceTrackerType::kUniversal: case FrameSequenceTrackerType::kUniversal:
return ThreadType::kSlower; return ThreadType::kSlower;
case FrameSequenceTrackerType::kCustom:
case FrameSequenceTrackerType::kMaxType: case FrameSequenceTrackerType::kMaxType:
NOTREACHED(); NOTREACHED();
} }
...@@ -230,6 +233,11 @@ void FrameSequenceMetrics::ReportMetrics() { ...@@ -230,6 +233,11 @@ void FrameSequenceMetrics::ReportMetrics() {
ThroughputData::ToTracedValue(impl_throughput_, main_throughput_), ThroughputData::ToTracedValue(impl_throughput_, main_throughput_),
"checkerboard", frames_checkerboarded_); "checkerboard", frames_checkerboarded_);
// Data for kCustom typed tracker is handled by caller instead being
// reported here.
if (type_ == FrameSequenceTrackerType::kCustom)
return;
ComputeAggregatedThroughput(); ComputeAggregatedThroughput();
// Report the throughput metrics. // Report the throughput metrics.
...@@ -337,6 +345,8 @@ FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() { ...@@ -337,6 +345,8 @@ FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() {
FrameSequenceMetrics* FrameSequenceTrackerCollection::StartSequence( FrameSequenceMetrics* FrameSequenceTrackerCollection::StartSequence(
FrameSequenceTrackerType type) { FrameSequenceTrackerType type) {
DCHECK_NE(FrameSequenceTrackerType::kCustom, type);
if (is_single_threaded_) if (is_single_threaded_)
return nullptr; return nullptr;
if (frame_trackers_.contains(type)) if (frame_trackers_.contains(type))
...@@ -352,6 +362,8 @@ FrameSequenceMetrics* FrameSequenceTrackerCollection::StartSequence( ...@@ -352,6 +362,8 @@ FrameSequenceMetrics* FrameSequenceTrackerCollection::StartSequence(
void FrameSequenceTrackerCollection::StopSequence( void FrameSequenceTrackerCollection::StopSequence(
FrameSequenceTrackerType type) { FrameSequenceTrackerType type) {
DCHECK_NE(FrameSequenceTrackerType::kCustom, type);
if (!frame_trackers_.contains(type)) if (!frame_trackers_.contains(type))
return; return;
...@@ -366,8 +378,30 @@ void FrameSequenceTrackerCollection::StopSequence( ...@@ -366,8 +378,30 @@ void FrameSequenceTrackerCollection::StopSequence(
removal_trackers_.push_back(std::move(tracker)); removal_trackers_.push_back(std::move(tracker));
} }
void FrameSequenceTrackerCollection::StartCustomSequence(int sequence_id) {
DCHECK(!base::Contains(custom_frame_trackers_, sequence_id));
custom_frame_trackers_[sequence_id] = base::WrapUnique(
new FrameSequenceTracker(FrameSequenceTrackerType::kCustom,
/*throughput_ukm_reporter=*/nullptr,
/*custom_sequence_id=*/sequence_id));
}
void FrameSequenceTrackerCollection::StopCustomSequence(int sequence_id) {
auto it = custom_frame_trackers_.find(sequence_id);
// This happens when an animation is aborted before starting.
if (it == custom_frame_trackers_.end())
return;
std::unique_ptr<FrameSequenceTracker> tracker = std::move(it->second);
custom_frame_trackers_.erase(it);
tracker->ScheduleTerminate();
removal_trackers_.push_back(std::move(tracker));
}
void FrameSequenceTrackerCollection::ClearAll() { void FrameSequenceTrackerCollection::ClearAll() {
frame_trackers_.clear(); frame_trackers_.clear();
custom_frame_trackers_.clear();
removal_trackers_.clear(); removal_trackers_.clear();
} }
...@@ -376,37 +410,47 @@ void FrameSequenceTrackerCollection::NotifyBeginImplFrame( ...@@ -376,37 +410,47 @@ void FrameSequenceTrackerCollection::NotifyBeginImplFrame(
RecreateTrackers(args); RecreateTrackers(args);
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_)
tracker.second->ReportBeginImplFrame(args); tracker.second->ReportBeginImplFrame(args);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportBeginImplFrame(args);
} }
void FrameSequenceTrackerCollection::NotifyBeginMainFrame( void FrameSequenceTrackerCollection::NotifyBeginMainFrame(
const viz::BeginFrameArgs& args) { const viz::BeginFrameArgs& args) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_)
tracker.second->ReportBeginMainFrame(args); tracker.second->ReportBeginMainFrame(args);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportBeginMainFrame(args);
} }
void FrameSequenceTrackerCollection::NotifyMainFrameProcessed( void FrameSequenceTrackerCollection::NotifyMainFrameProcessed(
const viz::BeginFrameArgs& args) { const viz::BeginFrameArgs& args) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_)
tracker.second->ReportMainFrameProcessed(args); tracker.second->ReportMainFrameProcessed(args);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportMainFrameProcessed(args);
} }
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);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportImplFrameCausedNoDamage(ack); tracker.second->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);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportMainFrameCausedNoDamage(args); tracker.second->ReportMainFrameCausedNoDamage(args);
}
} }
void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() { void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_)
tracker.second->PauseFrameProduction(); tracker.second->PauseFrameProduction();
for (auto& tracker : custom_frame_trackers_)
tracker.second->PauseFrameProduction();
} }
void FrameSequenceTrackerCollection::NotifySubmitFrame( void FrameSequenceTrackerCollection::NotifySubmitFrame(
...@@ -418,14 +462,19 @@ void FrameSequenceTrackerCollection::NotifySubmitFrame( ...@@ -418,14 +462,19 @@ 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);
} }
for (auto& tracker : custom_frame_trackers_) {
tracker.second->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);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportFrameEnd(args, main_args); tracker.second->ReportFrameEnd(args, main_args);
}
} }
void FrameSequenceTrackerCollection::NotifyFramePresented( void FrameSequenceTrackerCollection::NotifyFramePresented(
...@@ -433,6 +482,8 @@ void FrameSequenceTrackerCollection::NotifyFramePresented( ...@@ -433,6 +482,8 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
const gfx::PresentationFeedback& feedback) { const gfx::PresentationFeedback& feedback) {
for (auto& tracker : frame_trackers_) for (auto& tracker : frame_trackers_)
tracker.second->ReportFramePresented(frame_token, feedback); tracker.second->ReportFramePresented(frame_token, feedback);
for (auto& tracker : custom_frame_trackers_)
tracker.second->ReportFramePresented(frame_token, feedback);
for (auto& tracker : removal_trackers_) for (auto& tracker : removal_trackers_)
tracker->ReportFramePresented(frame_token, feedback); tracker->ReportFramePresented(frame_token, feedback);
...@@ -440,12 +491,23 @@ void FrameSequenceTrackerCollection::NotifyFramePresented( ...@@ -440,12 +491,23 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
for (auto& tracker : removal_trackers_) { for (auto& tracker : removal_trackers_) {
if (tracker->termination_status() == if (tracker->termination_status() ==
FrameSequenceTracker::TerminationStatus::kReadyForTermination) { FrameSequenceTracker::TerminationStatus::kReadyForTermination) {
// The tracker is ready to be terminated. Take the metrics from the // The tracker is ready to be terminated.
// tracker, merge with any outstanding metrics from previous trackers of // For non kCustom typed trackers, take the metrics from the tracker.
// the same type. If there are enough frames to report the metrics, then // merge with any outstanding metrics from previous trackers of the same
// report the metrics and destroy it. Otherwise, retain it to be merged // type. If there are enough frames to report the metrics, then report the
// with follow-up sequences. // metrics and destroy it. Otherwise, retain it to be merged with
// follow-up sequences.
// For kCustom typed trackers, put its result in |custom_tracker_results_|
// to be picked up by caller.
auto metrics = tracker->TakeMetrics(); auto metrics = tracker->TakeMetrics();
if (tracker->type() == FrameSequenceTrackerType::kCustom) {
custom_tracker_results_[tracker->custom_sequence_id()] =
metrics->main_throughput();
// |custom_tracker_results_| should be picked up timely.
DCHECK_LT(custom_tracker_results_.size(), 500u);
continue;
}
auto key = std::make_pair(tracker->type(), metrics->GetEffectiveThread()); auto key = std::make_pair(tracker->type(), metrics->GetEffectiveThread());
if (accumulated_metrics_.contains(key)) { if (accumulated_metrics_.contains(key)) {
metrics->Merge(std::move(accumulated_metrics_[key])); metrics->Merge(std::move(accumulated_metrics_[key]));
...@@ -514,6 +576,11 @@ FrameSequenceTrackerCollection::FrameSequenceTrackerActiveTypes() { ...@@ -514,6 +576,11 @@ FrameSequenceTrackerCollection::FrameSequenceTrackerActiveTypes() {
return encoded_types; return encoded_types;
} }
CustomTrackerResults
FrameSequenceTrackerCollection::TakeCustomTrackerResults() {
return std::move(custom_tracker_results_);
}
FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting( FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting(
FrameSequenceTrackerType type) { FrameSequenceTrackerType type) {
if (!frame_trackers_.contains(type)) if (!frame_trackers_.contains(type))
...@@ -534,16 +601,19 @@ void FrameSequenceTrackerCollection::SetUkmManager(UkmManager* manager) { ...@@ -534,16 +601,19 @@ void FrameSequenceTrackerCollection::SetUkmManager(UkmManager* manager) {
FrameSequenceTracker::FrameSequenceTracker( FrameSequenceTracker::FrameSequenceTracker(
FrameSequenceTrackerType type, FrameSequenceTrackerType type,
ThroughputUkmReporter* throughput_ukm_reporter) ThroughputUkmReporter* throughput_ukm_reporter,
int custom_sequence_id)
: type_(type), : type_(type),
custom_sequence_id_(custom_sequence_id),
metrics_(std::make_unique<FrameSequenceMetrics>(type, metrics_(std::make_unique<FrameSequenceMetrics>(type,
throughput_ukm_reporter)), throughput_ukm_reporter)),
trace_data_(metrics_.get()) { trace_data_(metrics_.get()) {
DCHECK_LT(type_, FrameSequenceTrackerType::kMaxType); DCHECK_LT(type_, FrameSequenceTrackerType::kMaxType);
DCHECK(type_ != FrameSequenceTrackerType::kCustom ||
custom_sequence_id_ >= 0);
} }
FrameSequenceTracker::~FrameSequenceTracker() { FrameSequenceTracker::~FrameSequenceTracker() = default;
}
void FrameSequenceTracker::ScheduleTerminate() { void FrameSequenceTracker::ScheduleTerminate() {
termination_status_ = TerminationStatus::kScheduledForTermination; termination_status_ = TerminationStatus::kScheduledForTermination;
......
...@@ -48,6 +48,8 @@ enum class FrameSequenceTrackerType { ...@@ -48,6 +48,8 @@ enum class FrameSequenceTrackerType {
kVideo = 6, kVideo = 6,
kWheelScroll = 7, kWheelScroll = 7,
kScrollbarScroll = 8, kScrollbarScroll = 8,
kCustom = 9, // Note that the metrics for kCustom are not reported on UMA,
// and instead are dispatched back to the LayerTreeHostClient.
kMaxType kMaxType
}; };
...@@ -150,6 +152,10 @@ class CC_EXPORT FrameSequenceMetrics { ...@@ -150,6 +152,10 @@ class CC_EXPORT FrameSequenceMetrics {
uint32_t frames_checkerboarded_ = 0; uint32_t frames_checkerboarded_ = 0;
}; };
// Map of kCustom tracker results keyed by a sequence id.
using CustomTrackerResults =
base::flat_map<int, FrameSequenceMetrics::ThroughputData>;
// Used for notifying attached FrameSequenceTracker's of begin-frames and // Used for notifying attached FrameSequenceTracker's of begin-frames and
// submitted frames. // submitted frames.
class CC_EXPORT FrameSequenceTrackerCollection { class CC_EXPORT FrameSequenceTrackerCollection {
...@@ -173,6 +179,16 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -173,6 +179,16 @@ class CC_EXPORT FrameSequenceTrackerCollection {
// for all submitted frames. // for all submitted frames.
void StopSequence(FrameSequenceTrackerType type); void StopSequence(FrameSequenceTrackerType type);
// Creates a kCustom tracker for the given sequence id. It is an error and
// DCHECKs if there is already a tracker associated with the sequence id.
void StartCustomSequence(int sequence_id);
// Schedules the kCustom tracker representing |sequence_id| for destruction.
// It is a no-op if there is no tracker associated with the sequence id.
// Similar to StopSequence above, the tracker instance is destroyed *after*
// the presentation feedbacks have been received for all submitted frames.
void StopCustomSequence(int sequence_id);
// Removes all trackers. This also immediately destroys all trackers that had // Removes all trackers. This also immediately destroys all trackers that had
// been scheduled for destruction, even if there are pending // been scheduled for destruction, even if there are pending
// presentation-feedbacks. This is typically used if the client no longer // presentation-feedbacks. This is typically used if the client no longer
...@@ -196,7 +212,9 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -196,7 +212,9 @@ class CC_EXPORT FrameSequenceTrackerCollection {
// Note that this notifies the trackers of the presentation-feedbacks, and // Note that this notifies the trackers of the presentation-feedbacks, and
// destroys any tracker that had been scheduled for destruction (using // destroys any tracker that had been scheduled for destruction (using
// |ScheduleRemoval()|) if it has no more pending frames. // |ScheduleRemoval()|) if it has no more pending frames. Data from non
// kCustom typed trackers are reported to UMA. Data from kCustom typed
// trackers are added to |custom_tracker_results_| for caller to pick up.
void NotifyFramePresented(uint32_t frame_token, void NotifyFramePresented(uint32_t frame_token,
const gfx::PresentationFeedback& feedback); const gfx::PresentationFeedback& feedback);
...@@ -205,6 +223,9 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -205,6 +223,9 @@ class CC_EXPORT FrameSequenceTrackerCollection {
// each type. // each type.
ActiveFrameSequenceTrackers FrameSequenceTrackerActiveTypes(); ActiveFrameSequenceTrackers FrameSequenceTrackerActiveTypes();
// Reports the accumulated kCustom tracker results and clears it.
CustomTrackerResults TakeCustomTrackerResults();
FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type); FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type);
void SetUkmManager(UkmManager* manager); void SetUkmManager(UkmManager* manager);
...@@ -219,6 +240,12 @@ class CC_EXPORT FrameSequenceTrackerCollection { ...@@ -219,6 +240,12 @@ class CC_EXPORT FrameSequenceTrackerCollection {
base::flat_map<FrameSequenceTrackerType, base::flat_map<FrameSequenceTrackerType,
std::unique_ptr<FrameSequenceTracker>> std::unique_ptr<FrameSequenceTracker>>
frame_trackers_; frame_trackers_;
// Custom trackers are keyed by a custom sequence id.
base::flat_map<int, std::unique_ptr<FrameSequenceTracker>>
custom_frame_trackers_;
CustomTrackerResults custom_tracker_results_;
std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_; std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_;
CompositorFrameReportingController* const CompositorFrameReportingController* const
compositor_frame_reporting_controller_; compositor_frame_reporting_controller_;
...@@ -304,6 +331,7 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -304,6 +331,7 @@ class CC_EXPORT FrameSequenceTracker {
FrameSequenceMetrics* metrics() { return metrics_.get(); } FrameSequenceMetrics* metrics() { return metrics_.get(); }
FrameSequenceTrackerType type() const { return type_; } FrameSequenceTrackerType type() const { return type_; }
int custom_sequence_id() const { return custom_sequence_id_; }
std::unique_ptr<FrameSequenceMetrics> TakeMetrics(); std::unique_ptr<FrameSequenceMetrics> TakeMetrics();
...@@ -312,7 +340,8 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -312,7 +340,8 @@ class CC_EXPORT FrameSequenceTracker {
friend class FrameSequenceTrackerTest; friend class FrameSequenceTrackerTest;
FrameSequenceTracker(FrameSequenceTrackerType type, FrameSequenceTracker(FrameSequenceTrackerType type,
ThroughputUkmReporter* throughput_ukm_reporter); ThroughputUkmReporter* throughput_ukm_reporter,
int custom_sequence_id = -1);
FrameSequenceMetrics::ThroughputData& impl_throughput() { FrameSequenceMetrics::ThroughputData& impl_throughput() {
return metrics_->impl_throughput(); return metrics_->impl_throughput();
...@@ -361,6 +390,7 @@ class CC_EXPORT FrameSequenceTracker { ...@@ -361,6 +390,7 @@ class CC_EXPORT FrameSequenceTracker {
bool ShouldIgnoreSequence(uint64_t sequence_number) const; bool ShouldIgnoreSequence(uint64_t sequence_number) const;
const FrameSequenceTrackerType type_; const FrameSequenceTrackerType type_;
const int custom_sequence_id_;
TerminationStatus termination_status_ = TerminationStatus::kActive; TerminationStatus termination_status_ = TerminationStatus::kActive;
......
...@@ -233,6 +233,9 @@ class FrameSequenceTrackerTest : public testing::Test { ...@@ -233,6 +233,9 @@ class FrameSequenceTrackerTest : public testing::Test {
unsigned NumberOfTrackers() const { unsigned NumberOfTrackers() const {
return collection_.frame_trackers_.size(); return collection_.frame_trackers_.size();
} }
unsigned NumberOfCustomTrackers() const {
return collection_.custom_frame_trackers_.size();
}
unsigned NumberOfRemovalTrackers() const { unsigned NumberOfRemovalTrackers() const {
return collection_.removal_trackers_.size(); return collection_.removal_trackers_.size();
} }
...@@ -1223,4 +1226,54 @@ TEST_F(FrameSequenceTrackerTest, TrackerTypeEncoding) { ...@@ -1223,4 +1226,54 @@ TEST_F(FrameSequenceTrackerTest, TrackerTypeEncoding) {
EXPECT_EQ(active_encoded, 16); // 1 << 4 EXPECT_EQ(active_encoded, 16); // 1 << 4
} }
TEST_F(FrameSequenceTrackerTest, CustomTrackers) {
// Start custom tracker 1.
collection_.StartCustomSequence(1);
EXPECT_EQ(1u, NumberOfCustomTrackers());
// No reports.
uint32_t frame_token = 1u;
collection_.NotifyFramePresented(frame_token, {});
auto results = collection_.TakeCustomTrackerResults();
EXPECT_EQ(0u, results.size());
// Start custom tracker 2 and 3 in addition to 1.
collection_.StartCustomSequence(2);
collection_.StartCustomSequence(3);
EXPECT_EQ(3u, NumberOfCustomTrackers());
// All custom trackers are running. No reports.
collection_.NotifyFramePresented(frame_token, {});
results = collection_.TakeCustomTrackerResults();
EXPECT_EQ(0u, results.size());
// Tracker 2 is stopped and scheduled to terminate.
collection_.StopCustomSequence(2);
EXPECT_EQ(2u, NumberOfCustomTrackers());
// Tracker 2 should report with no data.
collection_.NotifyFramePresented(frame_token, {});
results = collection_.TakeCustomTrackerResults();
EXPECT_EQ(1u, results.size());
EXPECT_EQ(0u, results[2].frames_expected);
// Simple sequence of one frame.
const char sequence[] = "b(1)B(0,1)s(1)S(1)e(1,0)P(1)";
GenerateSequence(sequence);
// Stop all custom trackers.
collection_.StopCustomSequence(1);
collection_.StopCustomSequence(3);
EXPECT_EQ(0u, NumberOfCustomTrackers());
// Tracker 1 and 3 and should report.
collection_.NotifyFramePresented(frame_token, {});
results = collection_.TakeCustomTrackerResults();
EXPECT_EQ(2u, results.size());
EXPECT_EQ(1u, results[1].frames_produced);
EXPECT_EQ(1u, results[1].frames_expected);
EXPECT_EQ(1u, results[3].frames_produced);
EXPECT_EQ(1u, results[3].frames_expected);
}
} // namespace cc } // namespace cc
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