[go: nahoru, domu]

Remove the V1 cc metrics path

The last of the usage of V1 metrics in ChromeOS was removed:
  https://chromium-review.googlesource.com/c/chromium/src/+/5213406

This change removes all of the path usage to calculate V1 metrics.
Several signals are no longer needed by FrameSequenceTacker as we use
the AddSortedFrame path for V3. This also removes old debugging traces
that are no longer needed, with PipelineReporter being easier to follow.
This should address the OoM seen in crbug.com/1518417

FrameSequenceTackerTest was overhauled to reflect the new signalling
and AddSortedFrame post processing.

This also removes V1 Graphics.Smoothness.*Stale as the final Finch
using it launched.

OBSOLETE_HISTOGRAM[Graphics.Smoothness.MaxStale]=finches complete, no longer needed
OBSOLETE_HISTOGRAM[Graphics.Smoothness.Stale]=finches complete, no longer needed

Bug: 1256879, 1518417
Change-Id: I526dec891fec850caeb5eb4e7e7305061b7c59be
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5224910
Reviewed-by: Kyle Charbonneau <kylechar@chromium.org>
Commit-Queue: Jonathan Ross <jonross@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1252174}
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index 7275f2a..3d797d2 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -198,8 +198,6 @@
     "metrics/frame_sequence_tracker_collection.h",
     "metrics/frame_sorter.cc",
     "metrics/frame_sorter.h",
-    "metrics/jank_metrics.cc",
-    "metrics/jank_metrics.h",
     "metrics/latency_ukm_reporter.cc",
     "metrics/latency_ukm_reporter.h",
     "metrics/lcd_text_metrics_reporter.cc",
@@ -771,7 +769,6 @@
     "metrics/frame_sequence_metrics_unittest.cc",
     "metrics/frame_sequence_tracker_unittest.cc",
     "metrics/frame_sorter_unittest.cc",
-    "metrics/jank_metrics_unittest.cc",
     "metrics/predictor_jank_tracker_unittest.cc",
     "metrics/scroll_jank_dropped_frame_tracker_unittest.cc",
     "metrics/scroll_jank_ukm_reporter_unittest.cc",
diff --git a/cc/metrics/frame_sequence_metrics.cc b/cc/metrics/frame_sequence_metrics.cc
index b118d37..e9a47c2 100644
--- a/cc/metrics/frame_sequence_metrics.cc
+++ b/cc/metrics/frame_sequence_metrics.cc
@@ -8,7 +8,6 @@
 #include <string>
 #include <utility>
 
-#include "base/metrics/histogram.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
@@ -16,9 +15,7 @@
 #include "base/trace_event/trace_event.h"
 #include "base/trace_event/traced_value.h"
 #include "cc/metrics/frame_sequence_tracker.h"
-#include "cc/metrics/jank_metrics.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
-#include "third_party/abseil-cpp/absl/base/attributes.h"
 
 namespace cc {
 
@@ -134,17 +131,7 @@
 FrameSequenceMetrics::V3::~V3() = default;
 
 FrameSequenceMetrics::FrameSequenceMetrics(FrameSequenceTrackerType type)
-    : type_(type) {
-  SmoothEffectDrivingThread thread_type = GetEffectiveThread();
-
-  // Only construct |jank_reporter_| if it has a valid tracker and thread type.
-  // For scrolling tracker types, |jank_reporter_| may be constructed later in
-  // SetScrollingThread().
-  if (thread_type == SmoothEffectDrivingThread::kCompositor ||
-      thread_type == SmoothEffectDrivingThread::kMain) {
-    jank_reporter_ = std::make_unique<JankMetrics>(type, thread_type);
-  }
-}
+    : type_(type) {}
 
 FrameSequenceMetrics::~FrameSequenceMetrics() {
   // If we did not see sufficient frames to report we will be kept around to
@@ -171,10 +158,6 @@
          type_ == FrameSequenceTrackerType::kScrollbarScroll);
   DCHECK_EQ(scrolling_thread_, SmoothEffectDrivingThread::kUnknown);
   scrolling_thread_ = scrolling_thread;
-
-  DCHECK(!jank_reporter_);
-  DCHECK_NE(scrolling_thread, SmoothEffectDrivingThread::kUnknown);
-  jank_reporter_ = std::make_unique<JankMetrics>(type_, scrolling_thread);
 }
 
 void FrameSequenceMetrics::SetCustomReporter(CustomReporter custom_reporter) {
@@ -217,8 +200,6 @@
   DCHECK_NE(type_, FrameSequenceTrackerType::kCustom);
   DCHECK_EQ(type_, metrics->type_);
   DCHECK_EQ(GetEffectiveThread(), metrics->GetEffectiveThread());
-  impl_throughput_.Merge(metrics->impl_throughput_);
-  main_throughput_.Merge(metrics->main_throughput_);
 
   v3_.frames_expected += metrics->v3_.frames_expected;
   v3_.frames_dropped += metrics->v3_.frames_dropped;
@@ -233,25 +214,14 @@
     v3_.last_frame_delta = metrics->v3_.last_frame_delta;
     v3_.no_update_duration = metrics->v3_.no_update_duration;
   }
-
-  if (jank_reporter_)
-    jank_reporter_->Merge(std::move(metrics->jank_reporter_));
-
-  // Reset the state of |metrics| before destroying it, so that it doesn't end
-  // up reporting the metrics.
-  metrics->impl_throughput_ = {};
-  metrics->main_throughput_ = {};
 }
 
 bool FrameSequenceMetrics::HasEnoughDataForReporting() const {
-  return impl_throughput_.frames_expected >= kMinFramesForThroughputMetric ||
-         main_throughput_.frames_expected >= kMinFramesForThroughputMetric ||
-         v3_.frames_expected >= kMinFramesForThroughputMetric;
+  return v3_.frames_expected >= kMinFramesForThroughputMetric;
 }
 
 bool FrameSequenceMetrics::HasDataLeftForReporting() const {
-  return impl_throughput_.frames_expected > 0 ||
-         main_throughput_.frames_expected > 0 || v3_.frames_expected > 0;
+  return v3_.frames_expected > 0;
 }
 
 void FrameSequenceMetrics::AdoptTrace(FrameSequenceMetrics* adopt_from) {
@@ -266,35 +236,8 @@
   adopt_from->trace_data_v3_.trace_id = 0u;
 }
 
-void FrameSequenceMetrics::AdvanceTrace(base::TimeTicks timestamp,
-                                        uint64_t sequence_number) {
-  uint32_t expected = 0, dropped = 0;
-  switch (GetEffectiveThread()) {
-    case SmoothEffectDrivingThread::kCompositor:
-      expected = impl_throughput_.frames_expected;
-      dropped =
-          impl_throughput_.frames_expected - impl_throughput_.frames_produced;
-      break;
-
-    case SmoothEffectDrivingThread::kMain:
-      expected = main_throughput_.frames_expected;
-      dropped =
-          main_throughput_.frames_expected - main_throughput_.frames_produced;
-      break;
-
-    case SmoothEffectDrivingThread::kUnknown:
-      NOTREACHED();
-  }
-  trace_data_.Advance(trace_data_.last_timestamp, timestamp, expected, dropped,
-                      sequence_number, "FrameSequenceTracker");
-}
-
 void FrameSequenceMetrics::ReportMetrics() {
-  DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected);
-  DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected);
-
   // Terminates |trace_data_| for all types of FrameSequenceTracker.
-  trace_data_.Terminate();
   trace_data_v3_.TerminateV3(v3_, GetEffectiveThread());
 
   if (type_ == FrameSequenceTrackerType::kCustom) {
@@ -306,10 +249,6 @@
             v3_.jank_count,
         });
 
-    main_throughput_ = {};
-    impl_throughput_ = {};
-    jank_reporter_->Reset();
-
     v3_.frames_expected = 0u;
     v3_.frames_dropped = 0u;
     v3_.frames_missing_content = 0u;
@@ -404,78 +343,6 @@
     v3_.no_update_count = 0u;
     v3_.jank_count = 0u;
   }
-
-  // Report the jank metrics
-  if (jank_reporter_) {
-    if (jank_reporter_->thread_type() ==
-            SmoothEffectDrivingThread::kCompositor &&
-        impl_throughput_.frames_expected >= kMinFramesForThroughputMetric) {
-      DCHECK_EQ(jank_reporter_->thread_type(), this->GetEffectiveThread());
-      jank_reporter_->ReportJankMetrics(impl_throughput_.frames_expected);
-    } else if (jank_reporter_->thread_type() ==
-                   SmoothEffectDrivingThread::kMain &&
-               main_throughput_.frames_expected >=
-                   kMinFramesForThroughputMetric) {
-      DCHECK_EQ(jank_reporter_->thread_type(), this->GetEffectiveThread());
-      jank_reporter_->ReportJankMetrics(main_throughput_.frames_expected);
-    }
-  }
-
-  // Reset the metrics that reach reporting threshold.
-  if (impl_throughput_.frames_expected >= kMinFramesForThroughputMetric)
-    impl_throughput_ = {};
-  if (main_throughput_.frames_expected >= kMinFramesForThroughputMetric)
-    main_throughput_ = {};
-}
-
-void FrameSequenceMetrics::ComputeJank(SmoothEffectDrivingThread thread_type,
-                                       uint32_t frame_token,
-                                       base::TimeTicks presentation_time,
-                                       base::TimeDelta frame_interval) {
-  if (!jank_reporter_)
-    return;
-
-  if (thread_type == jank_reporter_->thread_type())
-    jank_reporter_->AddPresentedFrame(frame_token, presentation_time,
-                                      frame_interval);
-}
-
-void FrameSequenceMetrics::NotifySubmitForJankReporter(
-    SmoothEffectDrivingThread thread_type,
-    uint32_t frame_token,
-    uint32_t sequence_number) {
-  if (!jank_reporter_)
-    return;
-
-  if (thread_type == jank_reporter_->thread_type())
-    jank_reporter_->AddSubmitFrame(frame_token, sequence_number);
-}
-
-void FrameSequenceMetrics::NotifyNoUpdateForJankReporter(
-    SmoothEffectDrivingThread thread_type,
-    uint32_t sequence_number,
-    base::TimeDelta frame_interval) {
-  if (!jank_reporter_)
-    return;
-
-  if (thread_type == jank_reporter_->thread_type())
-    jank_reporter_->AddFrameWithNoUpdate(sequence_number, frame_interval);
-}
-
-std::unique_ptr<base::trace_event::TracedValue>
-FrameSequenceMetrics::ThroughputData::ToTracedValue(
-    const ThroughputData& impl,
-    const ThroughputData& main,
-    SmoothEffectDrivingThread effective_thread) {
-  auto dict = std::make_unique<base::trace_event::TracedValue>();
-  if (effective_thread == SmoothEffectDrivingThread::kMain) {
-    dict->SetInteger("main-frames-produced", main.frames_produced);
-    dict->SetInteger("main-frames-expected", main.frames_expected);
-  } else {
-    dict->SetInteger("impl-frames-produced", impl.frames_produced);
-    dict->SetInteger("impl-frames-expected", impl.frames_expected);
-  }
-  return dict;
 }
 
 FrameSequenceMetrics::TraceData::TraceData(FrameSequenceMetrics* m)
@@ -485,17 +352,6 @@
 
 FrameSequenceMetrics::TraceData::~TraceData() = default;
 
-void FrameSequenceMetrics::TraceData::Terminate() {
-  if (!enabled || !trace_id)
-    return;
-  TRACE_EVENT_NESTABLE_ASYNC_END1(
-      "cc,benchmark", "FrameSequenceTracker", TRACE_ID_LOCAL(trace_id), "args",
-      ThroughputData::ToTracedValue(metrics->impl_throughput(),
-                                    metrics->main_throughput(),
-                                    metrics->GetEffectiveThread()));
-  trace_id = 0u;
-}
-
 void FrameSequenceMetrics::TraceData::TerminateV3(
     const V3& v3,
     FrameInfo::SmoothEffectDrivingThread effective_thread) {
diff --git a/cc/metrics/frame_sequence_metrics.h b/cc/metrics/frame_sequence_metrics.h
index 6896835a2..b5d08e138 100644
--- a/cc/metrics/frame_sequence_metrics.h
+++ b/cc/metrics/frame_sequence_metrics.h
@@ -22,7 +22,6 @@
 }  // namespace viz
 
 namespace cc {
-class JankMetrics;
 struct FrameInfo;
 
 enum class FrameSequenceTrackerType {
@@ -80,26 +79,6 @@
   FrameSequenceMetrics(const FrameSequenceMetrics&) = delete;
   FrameSequenceMetrics& operator=(const FrameSequenceMetrics&) = delete;
 
-  struct ThroughputData {
-    static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue(
-        const ThroughputData& impl,
-        const ThroughputData& main,
-        FrameInfo::SmoothEffectDrivingThread effective_thred);
-
-    void Merge(const ThroughputData& data) {
-      frames_expected += data.frames_expected;
-      frames_produced += data.frames_produced;
-    }
-
-    // Tracks the number of frames that were expected to be shown during this
-    // frame-sequence.
-    uint32_t frames_expected = 0;
-
-    // Tracks the number of frames that were actually presented to the user
-    // during this frame-sequence.
-    uint32_t frames_produced = 0;
-  };
-
   void SetScrollingThread(FrameInfo::SmoothEffectDrivingThread thread);
 
   struct CustomReportData {
@@ -124,33 +103,16 @@
   void AddSortedFrame(const viz::BeginFrameArgs& args,
                       const FrameInfo& frame_info);
 
-  ThroughputData& impl_throughput() { return impl_throughput_; }
-  ThroughputData& main_throughput() { return main_throughput_; }
-
   FrameSequenceTrackerType type() const { return type_; }
 
   // Must be called before destructor.
   void ReportLeftoverData();
 
   void AdoptTrace(FrameSequenceMetrics* adopt_from);
-  void AdvanceTrace(base::TimeTicks timestamp, uint64_t sequence_number);
-
-  void ComputeJank(FrameInfo::SmoothEffectDrivingThread thread_type,
-                   uint32_t frame_token,
-                   base::TimeTicks presentation_time,
-                   base::TimeDelta frame_interval);
-
-  void NotifySubmitForJankReporter(
-      FrameInfo::SmoothEffectDrivingThread thread_type,
-      uint32_t frame_token,
-      uint32_t sequence_number);
-
-  void NotifyNoUpdateForJankReporter(
-      FrameInfo::SmoothEffectDrivingThread thread_type,
-      uint32_t sequence_number,
-      base::TimeDelta frame_interval);
 
  private:
+  friend class FrameSequenceMetricsTest;
+  friend class FrameSequenceTrackerTest;
   // FrameInfo is a merger of two threads' frame production. We should only look
   // at the `final_state`, `last_presented_termination_time` and
   // `termination_time` for the GetEffectiveThread.
@@ -201,23 +163,17 @@
                  uint32_t dropped,
                  uint64_t sequence_number,
                  const char* histogram_name);
-    void Terminate();
     void TerminateV3(const V3& v3,
                      FrameInfo::SmoothEffectDrivingThread effective_thread);
   } trace_data_{this};
 
   TraceData trace_data_v3_{this};
 
-  ThroughputData impl_throughput_;
-  ThroughputData main_throughput_;
-
   FrameInfo::SmoothEffectDrivingThread scrolling_thread_ =
       FrameInfo::SmoothEffectDrivingThread::kUnknown;
 
   // Callback invoked to report metrics for kCustom typed sequence.
   CustomReporter custom_reporter_;
-
-  std::unique_ptr<JankMetrics> jank_reporter_;
 };
 
 bool ShouldReportForAnimation(FrameSequenceTrackerType sequence_type,
diff --git a/cc/metrics/frame_sequence_metrics_unittest.cc b/cc/metrics/frame_sequence_metrics_unittest.cc
index 769ec12..17cfd75 100644
--- a/cc/metrics/frame_sequence_metrics_unittest.cc
+++ b/cc/metrics/frame_sequence_metrics_unittest.cc
@@ -2,9 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "cc/metrics/frame_sequence_tracker.h"
+#include "cc/metrics/frame_sequence_metrics.h"
+
+#include <utility>
 
 #include "base/test/metrics/histogram_tester.h"
+#include "cc/metrics/frame_sequence_tracker.h"
 #include "cc/trees/ukm_manager.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -12,19 +15,35 @@
 
 namespace cc {
 
-TEST(FrameSequenceMetricsTest, MergeMetrics) {
+class FrameSequenceMetricsTest : public testing::Test {
+ public:
+  FrameSequenceMetricsTest() = default;
+  ~FrameSequenceMetricsTest() override = default;
+
+  void SetFramesExpectedAndProduced(FrameSequenceMetrics& metrics,
+                                    uint32_t frames_expected,
+                                    uint32_t frames_dropped);
+};
+
+void FrameSequenceMetricsTest::SetFramesExpectedAndProduced(
+    FrameSequenceMetrics& metrics,
+    uint32_t frames_expected,
+    uint32_t frames_dropped) {
+  metrics.v3_.frames_expected = frames_expected;
+  metrics.v3_.frames_dropped = frames_dropped;
+}
+
+TEST_F(FrameSequenceMetricsTest, MergeMetrics) {
   // Create a metric with only a small number of frames. It shouldn't report any
   // metrics.
   FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll);
-  first.impl_throughput().frames_expected = 20;
-  first.impl_throughput().frames_produced = 10;
+  SetFramesExpectedAndProduced(first, 20u, 10u);
   EXPECT_FALSE(first.HasEnoughDataForReporting());
 
   // Create a second metric with too few frames to report any metrics.
   auto second = std::make_unique<FrameSequenceMetrics>(
       FrameSequenceTrackerType::kTouchScroll);
-  second->impl_throughput().frames_expected = 90;
-  second->impl_throughput().frames_produced = 60;
+  SetFramesExpectedAndProduced(*second, 90u, 30u);
   EXPECT_FALSE(second->HasEnoughDataForReporting());
 
   // Merge the two metrics. The result should have enough frames to report
@@ -34,17 +53,15 @@
 }
 
 #if DCHECK_IS_ON()
-TEST(FrameSequenceMetricsTest, ScrollingThreadMergeMetrics) {
+TEST_F(FrameSequenceMetricsTest, ScrollingThreadMergeMetrics) {
   FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll);
   first.SetScrollingThread(FrameInfo::SmoothEffectDrivingThread::kCompositor);
-  first.impl_throughput().frames_expected = 20;
-  first.impl_throughput().frames_produced = 10;
+  SetFramesExpectedAndProduced(first, 20u, 10u);
 
   auto second = std::make_unique<FrameSequenceMetrics>(
       FrameSequenceTrackerType::kTouchScroll);
+  SetFramesExpectedAndProduced(*second, 50u, 40u);
   second->SetScrollingThread(FrameInfo::SmoothEffectDrivingThread::kMain);
-  second->main_throughput().frames_expected = 50;
-  second->main_throughput().frames_produced = 10;
 
   ASSERT_DEATH_IF_SUPPORTED(first.Merge(std::move(second)), "");
 }
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc
index 4988fad..d1cf24e 100644
--- a/cc/metrics/frame_sequence_tracker.cc
+++ b/cc/metrics/frame_sequence_tracker.cc
@@ -4,51 +4,14 @@
 
 #include "cc/metrics/frame_sequence_tracker.h"
 
-#include <algorithm>
-#include <memory>
-#include <string>
 #include <utility>
 
-#include "base/containers/contains.h"
-#include "base/containers/cxx20_erase.h"
-#include "base/functional/bind.h"
-#include "base/logging.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/notreached.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/traced_value.h"
 #include "components/viz/common/frame_sinks/begin_frame_args.h"
 #include "components/viz/common/quads/compositor_frame_metadata.h"
 #include "ui/gfx/presentation_feedback.h"
 
-// This macro is used with DCHECK to provide addition debug info.
-#if DCHECK_IS_ON()
-#define TRACKER_TRACE_STREAM frame_sequence_trace_
-#define TRACKER_DCHECK_MSG                                      \
-  " in " << GetFrameSequenceTrackerTypeName(this->type())       \
-         << " tracker: " << frame_sequence_trace_.str() << " (" \
-         << frame_sequence_trace_.str().size() << ")";
-#else
-#define TRACKER_TRACE_STREAM EAT_STREAM_PARAMETERS
-#define TRACKER_DCHECK_MSG ""
-#endif
-
 namespace cc {
 
-namespace {
-
-constexpr char kTraceCategory[] =
-    "cc,benchmark," TRACE_DISABLED_BY_DEFAULT("devtools.timeline.frame");
-
-}  // namespace
-
-using ThreadType = FrameInfo::SmoothEffectDrivingThread;
-
-// In the |TRACKER_TRACE_STREAM|, we mod the numbers such as frame sequence
-// number, or frame token, such that the debug string is not too long.
-constexpr int kDebugStrMod = 1000;
-
 const char* FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
     FrameSequenceTrackerType type) {
   switch (type) {
@@ -88,11 +51,6 @@
       metrics_(std::make_unique<FrameSequenceMetrics>(type)) {
   DCHECK_LT(type, FrameSequenceTrackerType::kMaxType);
   DCHECK(type != FrameSequenceTrackerType::kCustom);
-  // TODO(crbug.com/1158439): remove the trace event once the validation is
-  // completed.
-  TRACE_EVENT_NESTABLE_ASYNC_BEGIN_WITH_TIMESTAMP1(
-      kTraceCategory, "TrackerValidation", TRACE_ID_LOCAL(this),
-      base::TimeTicks::Now(), "name", GetFrameSequenceTrackerTypeName(type));
 }
 
 FrameSequenceTracker::FrameSequenceTracker(
@@ -106,10 +64,6 @@
 }
 
 FrameSequenceTracker::~FrameSequenceTracker() {
-  TRACE_EVENT_NESTABLE_ASYNC_END_WITH_TIMESTAMP2(
-      kTraceCategory, "TrackerValidation", TRACE_ID_LOCAL(this),
-      base::TimeTicks::Now(), "aborted_main", aborted_main_frame_,
-      "no_damage_main", no_damage_draw_main_frames_);
   CleanUp();
 }
 
@@ -132,174 +86,14 @@
   if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
     return;
 
-  TRACKER_TRACE_STREAM << "b(" << args.frame_id.sequence_number % kDebugStrMod
-                       << ")";
-
-  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
+  ResetAllStateIfPaused();
 
-  DCHECK_EQ(last_started_impl_sequence_, 0u) << TRACKER_DCHECK_MSG;
-  last_started_impl_sequence_ = args.frame_id.sequence_number;
-  if (reset_all_state_) {
-    begin_impl_frame_data_ = {};
-    begin_main_frame_data_ = {};
-    reset_all_state_ = false;
-  }
+  begin_impl_frame_data_.previous_source = args.frame_id.source_id;
+  begin_impl_frame_data_.previous_sequence = args.frame_id.sequence_number;
 
-  DCHECK(!frame_had_no_compositor_damage_) << TRACKER_DCHECK_MSG;
-  DCHECK(!compositor_frame_submitted_) << TRACKER_DCHECK_MSG;
-
-  UpdateTrackedFrameData(&begin_impl_frame_data_, args.frame_id.source_id,
-                         args.frame_id.sequence_number,
-                         args.frames_throttled_since_last);
-  impl_throughput().frames_expected +=
-      begin_impl_frame_data_.previous_sequence_delta;
-
-  if (first_frame_timestamp_.is_null())
-    first_frame_timestamp_ = args.frame_time;
-}
-
-void FrameSequenceTracker::ReportBeginMainFrame(
-    const viz::BeginFrameArgs& args) {
-  if (termination_status_ != TerminationStatus::kActive)
-    return;
-
-  if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
-    return;
-
-  TRACKER_TRACE_STREAM << "B("
-                       << begin_main_frame_data_.previous_sequence %
-                              kDebugStrMod
-                       << "," << args.frame_id.sequence_number % kDebugStrMod
-                       << ")";
-
-  if (first_received_main_sequence_ &&
-      first_received_main_sequence_ > args.frame_id.sequence_number) {
-    return;
-  }
-
-  if (!first_received_main_sequence_ &&
-      ShouldIgnoreSequence(args.frame_id.sequence_number)) {
-    return;
-  }
-
-#if DCHECK_IS_ON()
-  if (args.type == viz::BeginFrameArgs::NORMAL) {
-    DCHECK(impl_frames_.contains(args.frame_id)) << TRACKER_DCHECK_MSG;
-  }
-#endif
-
-  last_processed_main_sequence_latency_ = 0;
-  pending_main_sequences_.push_back(args.frame_id.sequence_number);
-
-  UpdateTrackedFrameData(&begin_main_frame_data_, args.frame_id.source_id,
-                         args.frame_id.sequence_number,
-                         args.frames_throttled_since_last);
-  if (!first_received_main_sequence_ ||
-      first_received_main_sequence_ <= last_no_main_damage_sequence_) {
-    first_received_main_sequence_ = args.frame_id.sequence_number;
-  }
-  main_throughput().frames_expected +=
-      begin_main_frame_data_.previous_sequence_delta;
-  previous_begin_main_sequence_ = current_begin_main_sequence_;
-  current_begin_main_sequence_ = args.frame_id.sequence_number;
-}
-
-void FrameSequenceTracker::ReportMainFrameProcessed(
-    const viz::BeginFrameArgs& args) {
-  if (termination_status_ != TerminationStatus::kActive)
-    return;
-
-  if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
-    return;
-
-  TRACKER_TRACE_STREAM << "E(" << args.frame_id.sequence_number % kDebugStrMod
-                       << ")";
-
-  const bool previous_main_frame_submitted_or_no_damage =
-      previous_begin_main_sequence_ != 0 &&
-      (last_submitted_main_sequence_ == previous_begin_main_sequence_ ||
-       last_no_main_damage_sequence_ == previous_begin_main_sequence_);
-  if (last_processed_main_sequence_ != 0 &&
-      !had_impl_frame_submitted_between_commits_ &&
-      !previous_main_frame_submitted_or_no_damage) {
-    DCHECK_GE(main_throughput().frames_expected,
-              begin_main_frame_data_.previous_sequence_delta)
-        << TRACKER_DCHECK_MSG;
-    main_throughput().frames_expected -=
-        begin_main_frame_data_.previous_sequence_delta;
-    last_no_main_damage_sequence_ = previous_begin_main_sequence_;
-  }
-  had_impl_frame_submitted_between_commits_ = false;
-
-  if (first_received_main_sequence_ &&
-      args.frame_id.sequence_number >= first_received_main_sequence_) {
-    DCHECK_EQ(last_processed_main_sequence_latency_, 0u) << TRACKER_DCHECK_MSG;
-    last_processed_main_sequence_ = args.frame_id.sequence_number;
-    last_processed_main_sequence_latency_ =
-        std::max(last_started_impl_sequence_, last_processed_impl_sequence_) -
-        args.frame_id.sequence_number;
-  }
-}
-
-void FrameSequenceTracker::ReportSubmitFrame(
-    uint32_t frame_token,
-    bool has_missing_content,
-    const viz::BeginFrameAck& ack,
-    const viz::BeginFrameArgs& origin_args) {
-  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;
-  }
-
-  last_processed_impl_sequence_ = ack.frame_id.sequence_number;
-  if (first_submitted_frame_ == 0)
-    first_submitted_frame_ = frame_token;
-  last_submitted_frame_ = frame_token;
-  compositor_frame_submitted_ = true;
-
-  TRACKER_TRACE_STREAM << "s(" << frame_token % kDebugStrMod << ")";
-  had_impl_frame_submitted_between_commits_ = true;
-  metrics()->NotifySubmitForJankReporter(
-      FrameInfo::SmoothEffectDrivingThread::kCompositor, frame_token,
-      ack.frame_id.sequence_number);
-
-  const bool main_changes_after_sequence_started =
-      first_received_main_sequence_ &&
-      origin_args.frame_id.sequence_number >= first_received_main_sequence_;
-  const bool main_changes_include_new_changes =
-      last_submitted_main_sequence_ == 0 ||
-      origin_args.frame_id.sequence_number > last_submitted_main_sequence_;
-  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) &&
-      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;
-      TRACKER_TRACE_STREAM << "S("
-                           << origin_args.frame_id.sequence_number %
-                                  kDebugStrMod
-                           << ")";
-      metrics()->NotifySubmitForJankReporter(
-          FrameInfo::SmoothEffectDrivingThread::kMain, frame_token,
-          origin_args.frame_id.sequence_number);
-
-      last_submitted_main_sequence_ = origin_args.frame_id.sequence_number;
-      main_frames_.push_back(frame_token);
-      DCHECK_GE(main_throughput().frames_expected, main_frames_.size())
-          << TRACKER_DCHECK_MSG;
-    }
+  if (!first_begin_frame_args_.IsValid()) {
+    first_begin_frame_args_ = args;
   }
 }
 
@@ -307,273 +101,32 @@
     const viz::BeginFrameArgs& args,
     const viz::BeginFrameArgs& main_args) {
   DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination);
-
-  if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
+  if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id)) {
     return;
-
-  // We only update the `pending_main_sequences` when the frame has successfully
-  // submitted, or when we determine that it has no damage. See
-  // ReportMainFrameCausedNoDamage. We do not do this in
-  // NotifyMainFrameProcessed, as that can occur during Commit, and we may yet
-  // determine at Draw that there was no damage.
-  while (!pending_main_sequences_.empty() &&
-         pending_main_sequences_.front() <=
-             main_args.frame_id.sequence_number) {
-    pending_main_sequences_.pop_front();
   }
-  TRACKER_TRACE_STREAM << "e(" << args.frame_id.sequence_number % kDebugStrMod
-                       << ","
-                       << main_args.frame_id.sequence_number % kDebugStrMod
-                       << ")";
 
   bool should_ignore_sequence =
-      ShouldIgnoreSequence(args.frame_id.sequence_number);
-  if (reset_all_state_) {
-    begin_impl_frame_data_ = {};
-    begin_main_frame_data_ = {};
-    reset_all_state_ = false;
-  }
-
-  if (should_ignore_sequence) {
-    is_inside_frame_ = false;
-    return;
-  }
-
-  if (compositor_frame_submitted_ && submitted_frame_had_new_main_content_ &&
-      last_processed_main_sequence_latency_) {
-    // If a compositor frame was submitted with new content from the
-    // main-thread, then make sure the latency gets accounted for.
-    main_throughput().frames_expected += last_processed_main_sequence_latency_;
-  }
-
-  // It is possible that the compositor claims there was no damage from the
-  // compositor, but before the frame ends, it submits a compositor frame (e.g.
-  // with some damage from main). In such cases, the compositor is still
-  // responsible for processing the update, and therefore the 'no damage' claim
-  // is ignored.
-  if (frame_had_no_compositor_damage_ && !compositor_frame_submitted_) {
-    DCHECK_GT(impl_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG;
-    --impl_throughput().frames_expected;
-    metrics()->NotifyNoUpdateForJankReporter(
-        FrameInfo::SmoothEffectDrivingThread::kCompositor,
-        args.frame_id.sequence_number, args.interval);
-    begin_impl_frame_data_.previous_sequence = 0;
-  }
-
-  frame_had_no_compositor_damage_ = false;
-  compositor_frame_submitted_ = false;
-  submitted_frame_had_new_main_content_ = false;
-  last_processed_main_sequence_latency_ = 0;
+      args.frame_id.sequence_number != begin_impl_frame_data_.previous_sequence;
+  ResetAllStateIfPaused();
   is_inside_frame_ = false;
 
-  DCHECK_EQ(last_started_impl_sequence_, last_processed_impl_sequence_)
-      << TRACKER_DCHECK_MSG;
-  last_started_impl_sequence_ = 0;
+  if (should_ignore_sequence) {
+    return;
+  }
 
   if (termination_status_ == TerminationStatus::kActive) {
     last_ended_frame_id_ = args.frame_id;
   }
 }
 
-void FrameSequenceTracker::ReportFramePresented(
-    uint32_t frame_token,
-    const gfx::PresentationFeedback& feedback) {
-  // TODO(xidachen): We should early exit if |last_submitted_frame_| = 0, as it
-  // means that we are presenting the same frame_token again.
-  const bool submitted_frame_since_last_presentation = !!last_submitted_frame_;
-  // !viz::FrameTokenGT(a, b) is equivalent to b >= a.
-  const bool frame_token_acks_last_frame =
-      !viz::FrameTokenGT(last_submitted_frame_, frame_token);
-
-  // Even if the presentation timestamp is null, we set last_submitted_frame_ to
-  // 0 such that the tracker can be terminated.
-  if (last_submitted_frame_ && frame_token_acks_last_frame)
-    last_submitted_frame_ = 0;
-
-  if (first_submitted_frame_ == 0 ||
-      viz::FrameTokenGT(first_submitted_frame_, frame_token)) {
-    // We are getting presentation feedback for frames that were submitted
-    // before this sequence started. So ignore these.
-    return;
-  }
-
-  TRACKER_TRACE_STREAM << "P(" << frame_token % kDebugStrMod << ")";
-
-  base::EraseIf(ignored_frame_tokens_, [frame_token](const uint32_t& token) {
-    return viz::FrameTokenGT(frame_token, token);
-  });
-  if (ignored_frame_tokens_.contains(frame_token))
-    return;
-
-  const auto vsync_interval =
-      (feedback.interval.is_zero() ? viz::BeginFrameArgs::DefaultInterval()
-                                   : feedback.interval);
-  DCHECK(!vsync_interval.is_zero()) << TRACKER_DCHECK_MSG;
-  const bool was_presented = !feedback.failed();
-  if (was_presented && submitted_frame_since_last_presentation) {
-    ++impl_throughput().frames_produced;
-    if (metrics()->GetEffectiveThread() == ThreadType::kCompositor) {
-      metrics()->AdvanceTrace(feedback.timestamp, frame_token);
-    }
-
-    metrics()->ComputeJank(FrameInfo::SmoothEffectDrivingThread::kCompositor,
-                           frame_token, feedback.timestamp, vsync_interval);
-  }
-
-  if (was_presented) {
-    // This presentation includes the visual update from all main frame tokens
-    // <= |frame_token|.
-    const unsigned size_before_erase = main_frames_.size();
-    while (!main_frames_.empty() &&
-           !viz::FrameTokenGT(main_frames_.front(), frame_token)) {
-      main_frames_.pop_front();
-    }
-    if (main_frames_.size() < size_before_erase) {
-      ++main_throughput().frames_produced;
-      if (metrics()->GetEffectiveThread() == ThreadType::kMain) {
-        metrics()->AdvanceTrace(feedback.timestamp, frame_token);
-      }
-
-      metrics()->ComputeJank(FrameInfo::SmoothEffectDrivingThread::kMain,
-                             frame_token, feedback.timestamp, vsync_interval);
-    }
-  }
-}
-
-void FrameSequenceTracker::ReportImplFrameCausedNoDamage(
-    const viz::BeginFrameAck& ack) {
-  DCHECK_NE(termination_status_, TerminationStatus::kReadyForTermination);
-
-  if (ShouldIgnoreBeginFrameSource(ack.frame_id.source_id))
-    return;
-
-  TRACKER_TRACE_STREAM << "n(" << ack.frame_id.sequence_number % kDebugStrMod
-                       << ")";
-
-  // This tracker would be scheduled to terminate, and this frame doesn't belong
-  // to that tracker.
-  if (ShouldIgnoreSequence(ack.frame_id.sequence_number))
-    return;
-
-  last_processed_impl_sequence_ = ack.frame_id.sequence_number;
-  // If there is no damage for this frame (and no frame is submitted), then the
-  // impl-sequence needs to be reset. However, this should be done after the
-  // processing the frame is complete (i.e. in ReportFrameEnd()), so that other
-  // notifications (e.g. 'no main damage' etc.) can be handled correctly.
-  DCHECK_EQ(begin_impl_frame_data_.previous_sequence,
-            ack.frame_id.sequence_number);
-  frame_had_no_compositor_damage_ = true;
-}
-
-void FrameSequenceTracker::ReportMainFrameCausedNoDamage(
-    const viz::BeginFrameArgs& args,
-    bool aborted) {
-  if (termination_status_ != TerminationStatus::kActive)
-    return;
-
-  if (ShouldIgnoreBeginFrameSource(args.frame_id.source_id))
-    return;
-
-  TRACKER_TRACE_STREAM << "N("
-                       << begin_main_frame_data_.previous_sequence %
-                              kDebugStrMod
-                       << "," << args.frame_id.sequence_number % kDebugStrMod
-                       << ")";
-
-  if (!first_received_main_sequence_ ||
-      first_received_main_sequence_ > args.frame_id.sequence_number) {
-    return;
-  }
-
-  if (last_no_main_damage_sequence_ == args.frame_id.sequence_number)
-    return;
-
-  auto initial_pending_size = pending_main_sequences_.size();
-  while (!pending_main_sequences_.empty() &&
-         pending_main_sequences_.front() <= args.frame_id.sequence_number) {
-    pending_main_sequences_.pop_front();
-  }
-  // If we didn't remove any `pending_main_sequences`, then we have previously
-  // submitted a CompositorFrame with damage for `args.frame_id.sequence_number`
-  // and the sequence is being re-used on a subsequent Impl frame. Which just
-  // happens to have no damage.
-  //
-  // This can occur when there is a Compositor Animation that is offscreen, and
-  // when we are awaiting the next BeginMainFrame to be Committed and Activated.
-  //
-  // We do not change the `main_throughput` expectations when the sequence is
-  // re-used.
-  if (pending_main_sequences_.size() == initial_pending_size)
-    return;
-
-  if (aborted)
-    ++aborted_main_frame_;
-  else
-    ++no_damage_draw_main_frames_;
-
-  DCHECK_GT(main_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG;
-  DCHECK_GT(main_throughput().frames_expected,
-            main_throughput().frames_produced)
-      << TRACKER_DCHECK_MSG;
-  last_no_main_damage_sequence_ = args.frame_id.sequence_number;
-  --main_throughput().frames_expected;
-  metrics()->NotifyNoUpdateForJankReporter(
-      FrameInfo::SmoothEffectDrivingThread::kMain,
-      args.frame_id.sequence_number, args.interval);
-
-  DCHECK_GE(main_throughput().frames_expected, main_frames_.size())
-      << TRACKER_DCHECK_MSG;
-
-  // Could be 0 if there were a pause frame production.
-  if (begin_main_frame_data_.previous_sequence != 0) {
-    DCHECK_GE(begin_main_frame_data_.previous_sequence,
-              args.frame_id.sequence_number)
-        << TRACKER_DCHECK_MSG;
-  }
-  begin_main_frame_data_.previous_sequence = 0;
-}
-
 void FrameSequenceTracker::PauseFrameProduction() {
   // The states need to be reset, so that the tracker ignores the vsyncs until
   // the next received begin-frame. However, defer doing that until the frame
   // ends (or a new frame starts), so that in case a frame is in-progress,
   // subsequent notifications for that frame can be handled correctly.
-  TRACKER_TRACE_STREAM << 'R';
   reset_all_state_ = true;
 }
 
-void FrameSequenceTracker::UpdateTrackedFrameData(
-    TrackedFrameData* frame_data,
-    uint64_t source_id,
-    uint64_t sequence_number,
-    uint64_t throttled_frame_count) {
-  if (frame_data->previous_sequence &&
-      frame_data->previous_source == source_id) {
-    uint32_t current_latency =
-        sequence_number - frame_data->previous_sequence - throttled_frame_count;
-    if (current_latency > 0u) {
-      frame_data->previous_sequence_delta = current_latency;
-    } else {
-      // It is possible for the `current_latency` to be 0. This can occur when
-      // the Renderer or VideoFrameSubmitter is detached from Viz as a client.
-      // Before being re-attached during the same frame. This can be caused by
-      // re-embedding this client. Such as when triggering Picture-in-Picture
-      // mode.
-      //
-      // These special-case re-embedding lead to the `source_id` staying the
-      // same. As it is the same instance of Viz.
-      //
-      // We do not want to error on such a transition, so we treat the
-      // transition as a single frame delta.
-      frame_data->previous_sequence_delta = 1;
-    }
-  } else {
-    frame_data->previous_sequence_delta = 1;
-  }
-  frame_data->previous_source = source_id;
-  frame_data->previous_sequence = sequence_number;
-}
-
 bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource(
     uint64_t source_id) const {
   if (begin_impl_frame_data_.previous_source == 0)
@@ -581,25 +134,24 @@
   return source_id != begin_impl_frame_data_.previous_source;
 }
 
-// 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 sequence_number != begin_impl_frame_data_.previous_sequence;
+void FrameSequenceTracker::ResetAllStateIfPaused() {
+  // TODO(crbug.com/1256879): With FrameSequenceMetrics handling
+  // FrameInfo::FrameFinalState::kNoUpdateDesired we likely do not need this
+  // anymore.
+  if (!reset_all_state_) {
+    return;
+  }
+  begin_impl_frame_data_ = {};
+  last_ended_frame_id_ = viz::BeginFrameId();
+  reset_all_state_ = false;
 }
 
 bool FrameSequenceTracker::ShouldReportMetricsNow(
     const viz::BeginFrameArgs& args) const {
   return metrics_->HasEnoughDataForReporting() &&
-         !first_frame_timestamp_.is_null() &&
-         args.frame_time - first_frame_timestamp_ >= time_delta_to_report_;
+         first_begin_frame_args_.IsValid() &&
+         args.frame_time - first_begin_frame_args_.frame_time >=
+             time_delta_to_report_;
 }
 
 std::unique_ptr<FrameSequenceMetrics> FrameSequenceTracker::TakeMetrics() {
@@ -613,6 +165,15 @@
 
 void FrameSequenceTracker::AddSortedFrame(const viz::BeginFrameArgs& args,
                                           const FrameInfo& frame_info) {
+  // We will begin receiving sorted frames upon creation. Ignore those that are
+  // from before the `first_begin_frame_args_` as they are not a part of this
+  // sequence.
+  if (!first_begin_frame_args_.IsValid() ||
+      args.frame_id.sequence_number <
+          first_begin_frame_args_.frame_id.sequence_number) {
+    return;
+  }
+
   // Do not process any frames once we are terminated.
   if (termination_status_ == TerminationStatus::kReadyForTermination) {
     return;
@@ -621,7 +182,8 @@
   // For trackers that scheduled for termination, only proceed to update
   // metrics for the frame if it is before the last ended frame.
   if (termination_status_ == TerminationStatus::kScheduledForTermination) {
-    if (last_ended_frame_id_.source_id != args.frame_id.source_id) {
+    if (!last_ended_frame_id_.IsSequenceValid() ||
+        last_ended_frame_id_.source_id != args.frame_id.source_id) {
       // Frame source changed so we will no longer receive updates for frames
       // we submitted to the old source.
       termination_status_ = TerminationStatus::kReadyForTermination;
diff --git a/cc/metrics/frame_sequence_tracker.h b/cc/metrics/frame_sequence_tracker.h
index eddef37..641c9ec2 100644
--- a/cc/metrics/frame_sequence_tracker.h
+++ b/cc/metrics/frame_sequence_tracker.h
@@ -20,7 +20,6 @@
 }
 
 namespace viz {
-struct BeginFrameAck;
 struct BeginFrameArgs;
 struct BeginFrameId;
 }  // namespace viz
@@ -28,9 +27,7 @@
 namespace cc {
 // Tracks a sequence of frames to determine the throughput. It tracks this by
 // tracking the vsync sequence-numbers (from |BeginFrameArgs::sequence_number|),
-// and the presentation-timestamps (from |gfx::PresentationFeedback|). It also
-// tracks which frames were expected to include update from the main-thread, and
-// which presented frames did include updates from the main-thread.
+// and the presentation-timestamps (from |gfx::PresentationFeedback|).
 // This object should be created through
 // FrameSequenceTrackerCollection::CreateTracker() API.
 class CC_EXPORT FrameSequenceTracker {
@@ -53,41 +50,11 @@
   // BeginFrameArgs.
   void ReportBeginImplFrame(const viz::BeginFrameArgs& args);
 
-  // Notifies the tracker when a BeginFrameArgs is dispatched to the main
-  // thread.
-  void ReportBeginMainFrame(const viz::BeginFrameArgs& args);
-
-  void ReportMainFrameProcessed(const viz::BeginFrameArgs& args);
-
-  // Notifies the tracker when the compositor submits a CompositorFrame.
-  // |origin_args| represents the BeginFrameArgs that triggered the update from
-  // the main-thread.
-  void ReportSubmitFrame(uint32_t frame_token,
-                         bool has_missing_content,
-                         const viz::BeginFrameAck& ack,
-                         const viz::BeginFrameArgs& origin_args);
-
+  // Notifies the tracker when the compositor thread has finished processing a
+  // BeginFrameArgs.
   void ReportFrameEnd(const viz::BeginFrameArgs& args,
                       const viz::BeginFrameArgs& main_args);
 
-  // Notifies the tracker of the presentation-feedback of a previously submitted
-  // CompositorFrame with |frame_token|.
-  void ReportFramePresented(uint32_t frame_token,
-                            const gfx::PresentationFeedback& feedback);
-
-  // Notifies the tracker that a CompositorFrame is not going to be submitted
-  // for a particular BeginFrameArgs because it did not cause any damage (visual
-  // change). Note that if a begin-main-frame was dispatched, then a separate
-  // call to |ReportMainFrameCausedNoDamage()| is made to notify that the
-  // main-thread did not cause any damage/updates.
-  void ReportImplFrameCausedNoDamage(const viz::BeginFrameAck& ack);
-
-  // Notifies the tracker that a |BeginFrameArgs| either was not dispatched to
-  // the main-thread (because it did not ask for it), or that a |BeginFrameArgs|
-  // that was dispatched to the main-thread did not cause any updates/damage.
-  void ReportMainFrameCausedNoDamage(const viz::BeginFrameArgs& args,
-                                     bool aborted);
-
   // Notifies that frame production has currently paused. This is typically used
   // for interactive frame-sequences, e.g. during touch-scroll.
   void PauseFrameProduction();
@@ -107,6 +74,10 @@
   // |metrics_| to report.
   void CleanUp();
 
+  // Called by FrameSorter, this delivers `frame_info` merging both Compositor
+  // and Main thread updates for the given `args`. These are sorted by the
+  // `viz::BeginFrameArgs::frame_id` so we do not have to perform our own
+  // analysis of interleaving frames.
   void AddSortedFrame(const viz::BeginFrameArgs& args,
                       const FrameInfo& frame_info);
 
@@ -120,13 +91,6 @@
   FrameSequenceTracker(int custom_sequence_id,
                        FrameSequenceMetrics::CustomReporter custom_reporter);
 
-  FrameSequenceMetrics::ThroughputData& impl_throughput() {
-    return metrics_->impl_throughput();
-  }
-  FrameSequenceMetrics::ThroughputData& main_throughput() {
-    return metrics_->main_throughput();
-  }
-
   void ScheduleTerminate();
 
   struct TrackedFrameData {
@@ -135,137 +99,38 @@
     // BeginFrameArgs.
     uint64_t previous_source = 0;
     uint64_t previous_sequence = 0;
-
-    // The difference in |BeginFrameArgs::sequence_number| fields of the last
-    // two processed BeginFrameArgs.
-    uint32_t previous_sequence_delta = 0;
   };
 
-  void UpdateTrackedFrameData(TrackedFrameData* frame_data,
-                              uint64_t source_id,
-                              uint64_t sequence_number,
-                              uint64_t throttled_frame_count);
-
   bool ShouldIgnoreBeginFrameSource(uint64_t source_id) const;
-
-  bool ShouldIgnoreSequence(uint64_t sequence_number) const;
+  void ResetAllStateIfPaused();
 
   const int custom_sequence_id_;
 
   TerminationStatus termination_status_ = TerminationStatus::kActive;
 
   TrackedFrameData begin_impl_frame_data_;
-  TrackedFrameData begin_main_frame_data_;
 
   std::unique_ptr<FrameSequenceMetrics> metrics_;
 
-  // Tracks the list of frame-tokens for compositor-frames that included new
-  // updates from the main-thread, whose presentation-feedback have not been
-  // received yet. When the presentation-feedback for a frame is received, the
-  // corresponding frame-token is removed from this collection.
-  base::circular_deque<uint32_t> main_frames_;
-
-  // Keeps track of the sequence-number of the first received begin-main-frame.
-  // This is used to ignore submitted frames that include updates from earlier
-  // begin-main-frames.
-  uint64_t first_received_main_sequence_ = 0;
-
-  // Keeps track of the first submitted compositor-frame. This is used to ignore
-  // reports from frames that were submitted before this tracker had been
-  // created.
-  uint32_t first_submitted_frame_ = 0;
-
-  // Keeps track of the latest submitted compositor-frame, so that it can
-  // determine when it has received presentation-feedback for submitted frames.
-  // This is used to decide when to terminate this FrameSequenceTracker object.
-  uint32_t last_submitted_frame_ = 0;
-
-  // Keeps track of the begin-main-frames that need to be processed. There can
-  // be multiple in-flight, as BeginMainFrame to ReadyToCommit can be longer
-  // than one `viz::BeginFrameArgs.interval`. When this occurs the Compositor
-  // can send the `n+1` sequence_number, only for the Commit for `n` to arrive
-  // and lead to frame production.
-  std::deque<uint64_t> pending_main_sequences_;
-  uint64_t aborted_main_frame_ = 0;
-  uint64_t no_damage_draw_main_frames_ = 0;
-
-  // Keeps track of the last sequence-number that produced a frame from the
-  // main-thread.
-  uint64_t last_submitted_main_sequence_ = 0;
-
-  // Keeps track of the last sequence-number that produced a frame that did not
-  // have any damage from the main-thread.
-  uint64_t last_no_main_damage_sequence_ = 0;
-
-  // The time when this tracker is created, or the time when it was previously
-  // scheduled to report histogram.
-  base::TimeTicks first_frame_timestamp_;
-
-  // Keeps track of whether the impl-frame being processed did not have any
-  // damage from the compositor (i.e. 'impl damage').
-  bool frame_had_no_compositor_damage_ = false;
-
-  // Keeps track of whether a CompositorFrame is submitted during the frame.
-  bool compositor_frame_submitted_ = false;
-  bool submitted_frame_had_new_main_content_ = false;
-
   // Keeps track of whether the frame-states should be reset.
   bool reset_all_state_ = false;
 
-  // A frame that is ignored at ReportSubmitFrame should never be presented.
-  // TODO(xidachen): this should not be necessary. Some webview tests seem to
-  // present a frame even if it is ignored by ReportSubmitFrame.
-  base::flat_set<uint32_t> ignored_frame_tokens_;
-
   // Report the throughput metrics every 5 seconds.
   const base::TimeDelta time_delta_to_report_ = base::Seconds(5);
 
-  uint64_t last_started_impl_sequence_ = 0;
-  uint64_t last_processed_impl_sequence_ = 0;
-
-  uint64_t last_processed_main_sequence_ = 0;
-  uint64_t last_processed_main_sequence_latency_ = 0;
-
-  // Handle off-screen main damage case. In this case, the sequence is typically
-  // like: b(1)B(0,1)E(1)n(1)e(1)b(2)n(2)e(2)...b(10)E(2)B(10,10)n(10)e(10).
-  // Note that between two 'E's, all the impl frames caused no damage, and
-  // no main frames were submitted or caused no damage.
-  bool had_impl_frame_submitted_between_commits_ = false;
-  uint64_t previous_begin_main_sequence_ = 0;
-  // TODO(xidachen): remove this one.
-  uint64_t current_begin_main_sequence_ = 0;
-
   // 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;
 
+  // The args for the first frame that started after the tracker was created.
+  viz::BeginFrameArgs first_begin_frame_args_;
+
   // Frame id of the last ended frame when the tracker is active.
   viz::BeginFrameId last_ended_frame_id_;
   // Frame id of the last sorted frame that the tracker was notified. If this is
   // at least equal to `last_ended_frame_id_` then we are no longer awaiting
   // frame feedback and can terminate immediately.
   viz::BeginFrameId last_sorted_frame_id_;
-
-#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
-  // 'B' = ReportBeginMainFrame(), 'N' = ReportMainFrameCausedNoDamage(),
-  // 'b' = ReportBeginImplFrame(), 'n' = ReportMainFrameCausedNoDamage(),
-  // 'S' = ReportSubmitFrame() and 'P' = ReportFramePresented().
-  // Note that |frame_sequence_trace_| is only defined and populated
-  // when DCHECK is on.
-  std::stringstream frame_sequence_trace_;
-
-  // |frame_sequence_trace_| can be very long, in some cases we just need a
-  // substring of it. This var tells us how many chars can be ignored from the
-  // beginning of that debug string.
-  unsigned ignored_trace_char_count_ = 0;
-
-  // If ReportBeginImplFrame is never called on a arg, then ReportBeginMainFrame
-  // should ignore that arg.
-  base::flat_set<viz::BeginFrameId> impl_frames_;
-#endif
 };
 
 }  // namespace cc
diff --git a/cc/metrics/frame_sequence_tracker_collection.cc b/cc/metrics/frame_sequence_tracker_collection.cc
index 306a66b..6bdb851e 100644
--- a/cc/metrics/frame_sequence_tracker_collection.cc
+++ b/cc/metrics/frame_sequence_tracker_collection.cc
@@ -199,44 +199,6 @@
     tracker.second->ReportBeginImplFrame(args);
 }
 
-void FrameSequenceTrackerCollection::NotifyBeginMainFrame(
-    const viz::BeginFrameArgs& args) {
-  for (auto& tracker : frame_trackers_)
-    tracker.second->ReportBeginMainFrame(args);
-  for (auto& tracker : custom_frame_trackers_)
-    tracker.second->ReportBeginMainFrame(args);
-}
-
-void FrameSequenceTrackerCollection::NotifyMainFrameProcessed(
-    const viz::BeginFrameArgs& args) {
-  for (auto& tracker : frame_trackers_)
-    tracker.second->ReportMainFrameProcessed(args);
-  for (auto& tracker : custom_frame_trackers_)
-    tracker.second->ReportMainFrameProcessed(args);
-}
-
-void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage(
-    const viz::BeginFrameAck& ack) {
-  for (auto& tracker : frame_trackers_)
-    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(
-    const viz::BeginFrameArgs& args,
-    bool aborted) {
-  for (auto& tracker : frame_trackers_)
-    tracker.second->ReportMainFrameCausedNoDamage(args, aborted);
-  for (auto& tracker : custom_frame_trackers_)
-    tracker.second->ReportMainFrameCausedNoDamage(args, aborted);
-}
-
 void FrameSequenceTrackerCollection::NotifyPauseFrameProduction() {
   for (auto& tracker : frame_trackers_)
     tracker.second->PauseFrameProduction();
@@ -244,32 +206,6 @@
     tracker.second->PauseFrameProduction();
 }
 
-void FrameSequenceTrackerCollection::NotifySubmitFrame(
-    uint32_t frame_token,
-    bool has_missing_content,
-    const viz::BeginFrameAck& ack,
-    const viz::BeginFrameArgs& origin_args) {
-  for (auto& tracker : frame_trackers_) {
-    tracker.second->ReportSubmitFrame(frame_token, has_missing_content, ack,
-                                      origin_args);
-  }
-  for (auto& tracker : custom_frame_trackers_) {
-    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);
-  }
-
-  // TODO(crbug.com/1072482): find a proper way to terminate a tracker. Please
-  // refer to details in FrameSequenceTracker::ReportSubmitFrame
-  DestroyTrackers();
-}
-
 void FrameSequenceTrackerCollection::NotifyFrameEnd(
     const viz::BeginFrameArgs& args,
     const viz::BeginFrameArgs& main_args) {
@@ -285,19 +221,6 @@
   DestroyTrackers();
 }
 
-void FrameSequenceTrackerCollection::NotifyFramePresented(
-    uint32_t frame_token,
-    const gfx::PresentationFeedback& feedback) {
-  for (auto& tracker : frame_trackers_)
-    tracker.second->ReportFramePresented(frame_token, feedback);
-  for (auto& tracker : custom_frame_trackers_)
-    tracker.second->ReportFramePresented(frame_token, feedback);
-  for (auto& tracker : removal_trackers_)
-    tracker->ReportFramePresented(frame_token, feedback);
-
-  DestroyTrackers();
-}
-
 void FrameSequenceTrackerCollection::DestroyTrackers() {
   for (auto& tracker : removal_trackers_) {
     if (tracker->termination_status() ==
diff --git a/cc/metrics/frame_sequence_tracker_collection.h b/cc/metrics/frame_sequence_tracker_collection.h
index 5592f5f..d13631b 100644
--- a/cc/metrics/frame_sequence_tracker_collection.h
+++ b/cc/metrics/frame_sequence_tracker_collection.h
@@ -15,12 +15,7 @@
 #include "cc/cc_export.h"
 #include "cc/metrics/frame_sequence_metrics.h"
 
-namespace gfx {
-struct PresentationFeedback;
-}
-
 namespace viz {
-struct BeginFrameAck;
 struct BeginFrameArgs;
 }  // namespace viz
 
@@ -81,27 +76,10 @@
 
   // Notifies all trackers of various events.
   void NotifyBeginImplFrame(const viz::BeginFrameArgs& args);
-  void NotifyBeginMainFrame(const viz::BeginFrameArgs& args);
-  void NotifyMainFrameProcessed(const viz::BeginFrameArgs& args);
-  void NotifyImplFrameCausedNoDamage(const viz::BeginFrameAck& ack);
-  void NotifyMainFrameCausedNoDamage(const viz::BeginFrameArgs& args,
-                                     bool aborted);
   void NotifyPauseFrameProduction();
-  void NotifySubmitFrame(uint32_t frame_token,
-                         bool has_missing_content,
-                         const viz::BeginFrameAck& ack,
-                         const viz::BeginFrameArgs& origin_args);
   void NotifyFrameEnd(const viz::BeginFrameArgs& args,
                       const viz::BeginFrameArgs& main_args);
 
-  // Note that this notifies the trackers of the presentation-feedbacks, and
-  // destroys any tracker that had been scheduled for destruction (using
-  // |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,
-                            const gfx::PresentationFeedback& feedback);
-
   // Return the type of each active frame tracker, encoded into a 16 bit
   // integer with the bit at each position corresponding to the enum value of
   // each type.
diff --git a/cc/metrics/frame_sequence_tracker_unittest.cc b/cc/metrics/frame_sequence_tracker_unittest.cc
index 99456af..03c14b9c 100644
--- a/cc/metrics/frame_sequence_tracker_unittest.cc
+++ b/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -74,31 +74,20 @@
                                        viz::BeginFrameArgs::NORMAL);
   }
 
-  void StartImplAndMainFrames(const viz::BeginFrameArgs& args) {
+  void StartFrames(const viz::BeginFrameArgs& args) {
     collection_.NotifyBeginImplFrame(args);
-    collection_.NotifyBeginMainFrame(args);
   }
 
   uint32_t DispatchCompleteFrame(const viz::BeginFrameArgs& args,
                                  uint32_t damage_type,
                                  bool has_missing_content = false) {
-    StartImplAndMainFrames(args);
+    StartFrames(args);
 
     if (damage_type & kImplDamage) {
-      if (!(damage_type & kMainDamage)) {
-        collection_.NotifyMainFrameCausedNoDamage(args, false);
-      } else {
-        collection_.NotifyMainFrameProcessed(args);
-      }
       uint32_t frame_token = NextFrameToken();
-      collection_.NotifySubmitFrame(frame_token, has_missing_content,
-                                    viz::BeginFrameAck(args, true), args);
       collection_.NotifyFrameEnd(args, args);
       return frame_token;
     } else {
-      collection_.NotifyImplFrameCausedNoDamage(
-          viz::BeginFrameAck(args, false));
-      collection_.NotifyMainFrameCausedNoDamage(args, true);
       collection_.NotifyFrameEnd(args, args);
     }
     return 0;
@@ -132,24 +121,23 @@
 
   void GenerateSequence(const char* str) {
     const uint64_t source_id = 1;
-    uint64_t current_frame = 0;
     viz::BeginFrameArgs last_activated_main_args;
     while (*str) {
       const char command = *str++;
       uint64_t sequence = 0, dummy = 0, last_activated_main = 0;
       switch (command) {
         case 'b':
+        case 'd':
+        case 'D':
+        case 'p':
         case 'P':
         case 'n':
-        case 's':
-        case 'E':
           ASSERT_EQ(*str, '(') << command;
           str = ParseNumber(++str, &sequence);
           ASSERT_EQ(*str, ')');
           ++str;
           break;
 
-        case 'B':
         case 'N':
           ASSERT_EQ(*str, '(');
           str = ParseNumber(++str, &dummy);
@@ -177,72 +165,71 @@
 
       switch (command) {
         case 'b':
-          current_frame = sequence;
           collection_.NotifyBeginImplFrame(
               CreateBeginFrameArgs(source_id, sequence));
           break;
 
-        case 'P':
-          collection_.NotifyFramePresented(
-              sequence, {base::TimeTicks::Now(),
-                         viz::BeginFrameArgs::DefaultInterval(), 0});
+        case 'd': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kDropped;
+          frame_info.smooth_thread = FrameInfo::SmoothThread::kSmoothCompositor;
+          collection_.AddSortedFrame(args, frame_info);
           break;
+        }
 
+        case 'D': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kDropped;
+          frame_info.smooth_thread = FrameInfo::SmoothThread::kSmoothMain;
+          collection_.AddSortedFrame(args, frame_info);
+          break;
+        }
+
+        case 'p': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kPresentedAll;
+          frame_info.smooth_thread = FrameInfo::SmoothThread::kSmoothCompositor;
+          collection_.AddSortedFrame(args, frame_info);
+          break;
+        }
+
+        case 'P': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kPresentedAll;
+          frame_info.smooth_thread = FrameInfo::SmoothThread::kSmoothMain;
+          collection_.AddSortedFrame(args, frame_info);
+          break;
+        }
         case 'R':
           collection_.NotifyPauseFrameProduction();
           break;
 
-        case 'n':
-          collection_.NotifyImplFrameCausedNoDamage(
-              viz::BeginFrameAck(source_id, sequence, false, 0));
-          break;
-
-        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') {
-            ++str;
-            ASSERT_EQ(*str, '(');
-            str = ParseNumber(++str, &sequence);
-            ASSERT_EQ(*str, ')');
-            ++str;
-            main_args = CreateBeginFrameArgs(source_id, sequence);
-          }
-          collection_.NotifySubmitFrame(
-              frame_token, /*has_missing_content=*/false,
-              viz::BeginFrameAck(args, true), main_args);
+        case 'n': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kNoUpdateDesired;
+          collection_.AddSortedFrame(args, frame_info);
           break;
         }
 
         case 'e': {
           auto args = CreateBeginFrameArgs(source_id, sequence);
-          if (last_activated_main != 0)
-            DCHECK_EQ(last_activated_main_args.frame_id.sequence_number,
-                      last_activated_main);
-          collection_.NotifyFrameEnd(args, last_activated_main_args);
-          FrameInfo frame_info;
-          frame_info.final_state = FrameInfo::FrameFinalState::kPresentedAll;
-          collection_.AddSortedFrame(args, frame_info);
+          collection_.NotifyFrameEnd(args, args);
           break;
         }
 
-        case 'E':
-          last_activated_main_args = CreateBeginFrameArgs(source_id, sequence);
-          collection_.NotifyMainFrameProcessed(last_activated_main_args);
+        case 'N': {
+          auto args = CreateBeginFrameArgs(source_id, sequence);
+          FrameInfo frame_info;
+          frame_info.final_state = FrameInfo::FrameFinalState::kNoUpdateDesired;
+          frame_info.smooth_thread = FrameInfo::SmoothThread::kSmoothMain;
+          collection_.AddSortedFrame(args, frame_info);
           break;
-
-        case 'B':
-          collection_.NotifyBeginMainFrame(
-              CreateBeginFrameArgs(source_id, sequence));
-          break;
-
-        case 'N':
-          collection_.NotifyMainFrameCausedNoDamage(
-              CreateBeginFrameArgs(source_id, sequence), true);
-          break;
+        }
 
         default:
           NOTREACHED();
@@ -270,30 +257,17 @@
     return tracker_->begin_impl_frame_data_.previous_sequence;
   }
 
-  uint64_t BeginMainFrameDataPreviousSequence() const {
-    return tracker_->begin_main_frame_data_.previous_sequence;
+  void IncrementFramesExpected(uint32_t frames) {
+    tracker_->metrics_->v3_.frames_expected += frames;
   }
 
-  base::flat_set<uint32_t> IgnoredFrameTokens() const {
-    return tracker_->ignored_frame_tokens_;
+  uint32_t frames_expected() const {
+    return tracker_->metrics_->v3_.frames_expected;
   }
 
-  FrameSequenceMetrics::ThroughputData& ImplThroughput(
-      FrameSequenceTracker* tracker) const {
-    return tracker->impl_throughput();
-  }
-
-  FrameSequenceMetrics::ThroughputData& ImplThroughput() const {
-    return tracker_->impl_throughput();
-  }
-
-  FrameSequenceMetrics::ThroughputData& MainThroughput(
-      FrameSequenceTracker* tracker) const {
-    return tracker->main_throughput();
-  }
-
-  FrameSequenceMetrics::ThroughputData& MainThroughput() const {
-    return tracker_->main_throughput();
+  uint32_t frames_produced() const {
+    return tracker_->metrics_->v3_.frames_expected -
+           tracker_->metrics_->v3_.frames_dropped;
   }
 
   FrameSequenceTracker::TerminationStatus GetTerminationStatus(
@@ -340,13 +314,6 @@
   uint64_t sequence_2 = 0;
   auto args_2 = CreateBeginFrameArgs(source_2, ++sequence_2);
   collection_.NotifyBeginImplFrame(args_2);
-  collection_.NotifyBeginMainFrame(args_2);
-  collection_.NotifyMainFrameCausedNoDamage(args_2, true);
-  // Since the main-frame did not have any new damage from the latest
-  // BeginFrameArgs, the submit-frame will carry the previous BeginFrameArgs
-  // (from source_1);
-  collection_.NotifySubmitFrame(NextFrameToken(), /*has_missing_content=*/false,
-                                viz::BeginFrameAck(args_2, true), args_1);
 }
 
 TEST_F(FrameSequenceTrackerTest, TestNotifyFramePresented) {
@@ -373,19 +340,17 @@
   // args.frame_time is less than 5s of the tracker creation time, so won't
   // schedule this tracker to report its throughput.
   collection_.NotifyBeginImplFrame(args);
-  collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false));
   collection_.NotifyFrameEnd(args, args);
 
   EXPECT_EQ(NumberOfTrackers(), 1u);
   EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
 
-  ImplThroughput().frames_expected += 101;
+  IncrementFramesExpected(101u);
   // Now args.frame_time is 5s since the tracker creation time, so this tracker
   // should be scheduled to report its throughput.
   args = CreateBeginFrameArgs(source, ++sequence,
                               args.frame_time + TimeDeltaToReport());
   collection_.NotifyBeginImplFrame(args);
-  collection_.NotifyImplFrameCausedNoDamage(viz::BeginFrameAck(args, false));
   collection_.NotifyFrameEnd(args, args);
   FrameInfo frame_info;
   frame_info.final_state = FrameInfo::FrameFinalState::kPresentedAll;
@@ -395,45 +360,6 @@
   EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
 }
 
-TEST_F(FrameSequenceTrackerTest, ReportWithoutBeginImplFrame) {
-  const uint64_t source = 1;
-  uint64_t sequence = 0;
-
-  auto args = CreateBeginFrameArgs(source, ++sequence);
-  collection_.NotifyBeginMainFrame(args);
-
-  EXPECT_EQ(BeginImplFrameDataPreviousSequence(), 0u);
-  // Call to ReportBeginMainFrame should early exit.
-  EXPECT_EQ(BeginMainFrameDataPreviousSequence(), 0u);
-
-  uint32_t frame_token = NextFrameToken();
-  collection_.NotifySubmitFrame(frame_token, false,
-                                viz::BeginFrameAck(args, true), args);
-
-  // Call to ReportSubmitFrame should early exit.
-  EXPECT_TRUE(IgnoredFrameTokens().contains(frame_token));
-
-  gfx::PresentationFeedback feedback;
-  collection_.NotifyFramePresented(frame_token, feedback);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
-}
-
-TEST_F(FrameSequenceTrackerTest, MainFrameTracking) {
-  const uint64_t source = 1;
-  uint64_t sequence = 0;
-
-  auto args = CreateBeginFrameArgs(source, ++sequence);
-  auto frame_1 = DispatchCompleteFrame(args, kImplDamage | kMainDamage);
-
-  args = CreateBeginFrameArgs(source, ++sequence);
-  auto frame_2 = DispatchCompleteFrame(args, kImplDamage);
-
-  gfx::PresentationFeedback feedback;
-  collection_.NotifyFramePresented(frame_1, feedback);
-  collection_.NotifyFramePresented(frame_2, feedback);
-}
-
 TEST_F(FrameSequenceTrackerTest, MainFrameNoDamageTracking) {
   const uint64_t source = 1;
   uint64_t sequence = 0;
@@ -443,170 +369,116 @@
 
   // Now, start the next frame, but for main, respond with the previous args.
   const auto second_args = CreateBeginFrameArgs(source, ++sequence);
-  StartImplAndMainFrames(second_args);
+  StartFrames(second_args);
 
-  uint32_t frame_token = NextFrameToken();
-  collection_.NotifySubmitFrame(frame_token, /*has_missing_content=*/false,
-                                viz::BeginFrameAck(second_args, true),
-                                first_args);
   collection_.NotifyFrameEnd(second_args, second_args);
 
   // Start and submit the next frame, with no damage from main.
   auto args = CreateBeginFrameArgs(source, ++sequence);
   collection_.NotifyBeginImplFrame(args);
-  frame_token = NextFrameToken();
-  collection_.NotifySubmitFrame(frame_token, /*has_missing_content=*/false,
-                                viz::BeginFrameAck(args, true), first_args);
   collection_.NotifyFrameEnd(args, args);
 
   // Now, submit a frame with damage from main from |second_args|.
-  collection_.NotifyMainFrameProcessed(second_args);
   args = CreateBeginFrameArgs(source, ++sequence);
-  StartImplAndMainFrames(args);
-  frame_token = NextFrameToken();
-  collection_.NotifySubmitFrame(frame_token, /*has_missing_content=*/false,
-                                viz::BeginFrameAck(args, true), second_args);
+  StartFrames(args);
   collection_.NotifyFrameEnd(args, args);
 }
 
 TEST_F(FrameSequenceTrackerTest, SimpleSequenceOneFrame) {
-  const char sequence[] = "b(1)B(0,1)s(1)S(1)e(1,0)P(1)";
+  const char sequence[] = "b(1)e(1,0)P(1)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 1u);
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_expected(), 1u);
+  EXPECT_EQ(frames_produced(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, SimpleSequenceOneFrameNoDamage) {
-  const char sequence[] = "b(1)B(0,1)N(1,1)n(1)e(1,0)";
+  const char sequence[] = "b(1)N(1,1)n(1)e(1,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 2u);
+  EXPECT_EQ(frames_produced(), 2u);
 
-  const char second_sequence[] = "b(2)B(1,2)n(2)N(2,2)e(2,0)";
+  const char second_sequence[] = "b(2)n(2)N(2,2)e(2,0)";
   GenerateSequence(second_sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 4u);
+  EXPECT_EQ(frames_produced(), 4u);
 }
 
 TEST_F(FrameSequenceTrackerTest, MultipleNoDamageNotifications) {
   const char sequence[] = "b(1)n(1)n(1)e(1,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 2u);
+  EXPECT_EQ(frames_produced(), 2u);
 }
 
 TEST_F(FrameSequenceTrackerTest, MultipleNoDamageNotificationsFromMain) {
-  const char sequence[] = "b(1)B(0,1)N(1,1)n(1)N(0,1)e(1,0)";
+  const char sequence[] = "b(1)N(1,1)n(1)N(0,1)e(1,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 3u);
+  EXPECT_EQ(frames_produced(), 3u);
 }
 
 TEST_F(FrameSequenceTrackerTest, DelayedMainFrameNoDamage) {
-  const char sequence[] =
-      "b(1)B(0,1)n(1)e(1,0)b(2)n(2)e(2,0)b(3)N(0,1)n(3)e(3,0)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)n(1)e(1,0)b(2)n(2)e(2,0)b(3)N(0,1)n(3)e(3,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
+  EXPECT_EQ(frames_produced(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, DelayedMainFrameNoDamageFromOlderFrame) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   // Start a sequence, and receive a 'no damage' from an earlier frame.
-  const char second_sequence[] = "b(2)B(0,2)N(2,1)n(2)N(2,2)e(2,0)";
+  const char second_sequence[] = "b(2)N(2,1)n(2)N(2,2)e(2,0)";
   GenerateSequence(second_sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
+  EXPECT_EQ(frames_produced(), 0u);
 }
 
 // This tests when a BeginMainFrame leads to No Damage, after the next Main
 // Frame has started. This should not crash.
 TEST_F(FrameSequenceTrackerTest, DelayedMainFrameNoDamageAfterNextMainFrame) {
-  const char sequence[] =
-      "b(1)B(0,1)n(1)e(1,0)E(1)b(2)B(0,2)N(0,1)n(2)N(0,2)e(2,0)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)n(1)e(1,0)b(2)N(0,1)n(2)N(0,2)e(2,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
+  EXPECT_EQ(frames_produced(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, StateResetDuringSequence) {
-  const char sequence[] = "b(1)B(0,1)n(1)N(1,1)Re(1,0)b(2)n(2)e(2,0)";
+  const char sequence[] = "b(1)n(1)N(1,1)Re(1,0)b(2)n(2)e(2,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
-}
-
-TEST_F(FrameSequenceTrackerTest, NoCompositorDamageSubmitFrame) {
-  const char sequence[] = "b(1)n(1)B(0,1)E(1)s(1)S(1)e(1,1)P(1)b(2)";
-  GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 2u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 1u);
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_expected(), 3u);
+  EXPECT_EQ(frames_produced(), 3u);
 }
 
 TEST_F(FrameSequenceTrackerTest, SequenceStateResetsDuringFrame) {
   const char sequence[] = "b(1)Rn(1)e(1,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 0u);
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
+  EXPECT_EQ(frames_expected(), 1u);
+  EXPECT_EQ(frames_produced(), 1u);
 
-  GenerateSequence("b(2)s(1)e(2,0)P(1)b(4)");
-  EXPECT_EQ(ImplThroughput().frames_expected, 3u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 1u);
-  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, 4u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 1u);
+  GenerateSequence("b(2)e(2,0)P(1)b(4)");
+  EXPECT_EQ(frames_expected(), 2u);
+  EXPECT_EQ(frames_produced(), 2u);
 }
 
 // b(2417)B(0,2417)E(2417)n(2417)N(2417,2417)
 TEST_F(FrameSequenceTrackerTest, SequenceNumberReset) {
-  const char sequence[] =
-      "b(6)B(0,6)n(6)e(6,0)Rb(1)B(0,1)N(1,1)n(1)e(1,0)b(2)B(1,2)n(2)e(2,0)";
+  const char sequence[] = "b(6)n(6)e(6,0)Rb(1)N(1,1)n(1)e(1,0)b(2)n(2)e(2,0)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  EXPECT_EQ(frames_expected(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, MainThroughputWithHighLatency) {
-  const char sequence[] = "b(1)B(0,1)n(1)e(1,0)b(2)E(1)s(1)S(1)e(2,1)P(1)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)n(1)e(1,0)b(2)e(2,1)P(1)D(1)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(ImplThroughput().frames_produced, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 2u);
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_expected(), 2u);
+  EXPECT_EQ(frames_produced(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame1) {
-  GenerateSequence("b(1)s(1)e(1,0)b(4)");
+  GenerateSequence("b(1)e(1,0)b(4)e(4,0)");
   collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
   EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
   FrameSequenceTracker* removal_tracker =
@@ -622,26 +494,16 @@
             FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
 }
 
-// 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(GetTerminationStatus(removal_tracker),
-            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
-  GenerateSequence("s(1)P(1)");
-  EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
-  EXPECT_EQ(GetTerminationStatus(removal_tracker),
-            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
-}
-
-TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame6) {
-  GenerateSequence("b(1)s(1)");
+// All the following cases are for one complete impl + one incomplete:
+// b(1)e(1,0)xxxxxxxxP(1)
+// The 'xxxxx' is an incomplete impl frame that has no damage, it could be
+// 1. b(2)e(2,0)P(1)n(2), and StopSequence happens anywhere after e and
+//    before P.
+// 2. b(2)e(2,0)P(1)n(2), and StopSequence can happen anywhere after e and
+//    before P. In this case, the tracker is not ready for termination yet at P
+//    because the sorted n(2) has not been called yet.
+TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame10) {
+  GenerateSequence("b(1)e(1,0)b(2)e(2,0)");
   collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
   EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
   FrameSequenceTracker* removal_tracker =
@@ -655,31 +517,8 @@
             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, 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(GetTerminationStatus(removal_tracker),
-            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
-  GenerateSequence("n(2)P(1)");
-  EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
-  EXPECT_EQ(GetTerminationStatus(removal_tracker),
-            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
-}
-
 TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame11) {
-  GenerateSequence("b(1)s(1)e(1,0)b(2)n(2)");
+  GenerateSequence("b(1)e(1,0)b(2)e(2,0)");
   collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
   EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
   FrameSequenceTracker* removal_tracker =
@@ -695,182 +534,164 @@
 
 // This test ensure that the tracker would terminate at e.
 TEST_F(FrameSequenceTrackerTest, TrackLastImplFrame24) {
-  GenerateSequence("b(1)s(1)P(1)");
+  GenerateSequence("b(1)P(1)");
   collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
   EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
-  GenerateSequence("e(1,0)");
+  GenerateSequence("e(1,0)p(1)");
   EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
 }
 
-TEST_F(FrameSequenceTrackerTest, IgnoredFrameTokensRemovedAtPresentation1) {
-  GenerateSequence("b(5)s(1)e(5,0)P(1)");
-  auto args = CreateBeginFrameArgs(/*source_id=*/1u, 1u);
-  // Ack to an impl frame that doesn't exist in this tracker.
-  collection_.NotifySubmitFrame(2, /*has_missing_content=*/false,
-                                viz::BeginFrameAck(args, true), args);
-  EXPECT_EQ(IgnoredFrameTokens().size(), 1u);
-  GenerateSequence("P(3)");
-  // Any token that is < 3 should have been removed.
-  EXPECT_EQ(IgnoredFrameTokens().size(), 0u);
-}
-
-// 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());
+// Termination is triggered after a new tree is committed and activated. Due to
+// this we will have started a BeginImplFrame that is not actually a part of the
+// sequence. When this occurs we terminate as soon as the most recently
+// submitted frame has bee processed.
+TEST_F(FrameSequenceTrackerTest, IgnoreImplFrameBeforeTermination) {
+  GenerateSequence("b(1)e(1,0)b(2)");
+  collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
+  EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
+  FrameSequenceTracker* removal_tracker =
+      collection_.GetRemovalTrackerForTesting(
+          FrameSequenceTrackerType::kTouchScroll);
+  EXPECT_EQ(GetTerminationStatus(removal_tracker),
+            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
+  GenerateSequence("e(2,0)");
+  EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
+  EXPECT_EQ(GetTerminationStatus(removal_tracker),
+            FrameSequenceTracker::TerminationStatus::kScheduledForTermination);
+  GenerateSequence("P(1)");
+  EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, TerminationWithNullPresentationTimeStamp) {
-  GenerateSequence("b(1)s(1)");
+  GenerateSequence("b(1)");
   collection_.StopSequence(FrameSequenceTrackerType::kTouchScroll);
   EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
   // Even if the presentation timestamp is null, as long as this presentation
   // is acking the last impl frame, we consider that impl frame completed and
   // so the tracker is ready for termination.
-  collection_.NotifyFramePresented(
-      1, {base::TimeTicks(), viz::BeginFrameArgs::DefaultInterval(), 0});
-  GenerateSequence("e(1,0)");
+  GenerateSequence("e(1,0)p(1)");
   EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage1) {
-  const char sequence[] =
-      "b(1)B(0,1)n(1)e(1,0)b(2)E(1)B(1,2)n(2)e(2,1)b(3)E(2)B(2,3)n(3)e(3,2)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)n(1)e(1,0)b(2)n(2)e(2,1)b(3)n(3)e(3,2)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
   // At E(2), B(0,1) is treated no damage.
-  EXPECT_EQ(MainThroughput().frames_expected, 2u);
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage2) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(1)B(0,1)n(1)e(1,0)b(2)E(1)B(1,2)n(2)e(2,1)b(3)n(3)e(3,1)b(4)n(4)e(4,1)"
-      "b(8)E(2)"
-      "B(8,8)n(8)e(8,2)";
+      "b(1)n(1)e(1,0)b(2)n(2)e(2,1)b(3)n(3)e(3,1)b(4)n(4)e(4,1)b(8)n(8)e(8,2)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
   // At E(2), B(0,1) is treated as no damage.
-  EXPECT_EQ(MainThroughput().frames_expected, 7u);
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage3) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(34)B(0,34)n(34)e(34,0)b(35)n(35)e(35,0)b(36)E(34)n(36)e(36,34)b(39)s("
-      "1)e(39,34)";
+      "b(34)n(34)e(34,0)b(35)n(35)e(35,0)b(36)n(36)e(36,34)b(39)e(39,34)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 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)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(9)n(9)Re(9,0)b(11)n(11)e(11,9)b(12)e(12,11)b(13)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 2u);
-  EXPECT_EQ(MainThroughput().frames_expected, 2u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage5) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(1)B(0,1)E(1)s(1)S(1)e(1,0)b(2)n(2)e(2,0)b(3)B(1,3)n(3)e(3,0)E(3)b(4)B("
-      "3,4)n("
-      "4)e(4,3)E(4)";
+      "b(1)e(1,0)b(2)n(2)e(2,0)b(3)n(3)e(3,0)b(4)n(4)e(4,3)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
   // At E(4), we treat B(1,3) as if it had no damage.
-  EXPECT_EQ(MainThroughput().frames_expected, 3u);
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage6) {
-  const char sequence[] =
-      "b(1)B(0,1)E(1)s(1)S(1)e(1,1)b(2)B(1,2)E(2)n(2)N(2,2)e(2,2)b(3)B(0,3)E(3)"
-      "n(3)"
-      "N(3,3)e(3,3)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)e(1,1)b(2)n(2)N(2,2)e(2,2)b(3)n(3)N(3,3)e(3,3)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage7) {
-  const char sequence[] =
-      "b(8)B(0,8)n(8)e(8,0)b(9)E(8)B(8,9)E(9)s(1)S(8)e(9,9)b(10)s(2)S(9)e(10,"
-      "9)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(8)n(8)e(8,0)b(9)e(9,9)b(10)e(10,9)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 2u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage8) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(18)B(0,18)E(18)n(18)N(18,18)Re(18,18)b(20)B(0,20)N(20,20)n(20)N(0,20)"
-      "e("
-      "20,18)b(21)B(0,21)E(21)s(1)S(21)e(21,21)";
+      "b(18)n(18)N(18,18)Re(18,18)b(20)N(20,20)n(20)N(0,20)e(20,18)b(21)e(21,"
+      "21)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage9) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(78)n(78)Re(78,0)Rb(82)B(0,82)E(82)n(82)N(82,82)Re(82,82)b(86)B(0,86)E("
-      "86)n("
-      "86)e(86,86)b(87)s(1)S(86)e(87,86)";
+      "b(78)n(78)Re(78,0)Rb(82)n(82)N(82,82)Re(82,82)b(86)n(86)e(86,86)b(87)e("
+      "87,86)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  // No damage frames are not expected.
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 TEST_F(FrameSequenceTrackerTest, OffScreenMainDamage10) {
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
   const char sequence[] =
-      "b(2)B(0,2)E(2)n(2)N(2,2)e(2,2)b(3)B(0,3)E(3)n(3)N(3,3)e(3,3)b(4)B(0,4)E("
-      "4)n("
-      "4)N(4,4)e(4,4)b(5)B(0,5)E(5)n(5)N(5,5)e(5,5)b(6)B(0,6)n(6)e(6,5)E(6)Rb("
-      "8)B(0,"
-      "8)E(8)n(8)N(8,8)e(8,8)";
+      "b(2)n(2)N(2,2)e(2,2)b(3)n(3)N(3,3)e(3,3)b(4)n(4)N(4,4)e(4,4)b(5)n(5)N(5,"
+      "5)e(5,5)b(6)n(6)e(6,5)Rb(8)n(8)N(8,8)e(8,8)";
   GenerateSequence(sequence);
-  EXPECT_EQ(ImplThroughput().frames_expected, 0u);
-  EXPECT_EQ(MainThroughput().frames_expected, 0u);
+  EXPECT_EQ(frames_expected(), 0u);
 }
 
 // A presentation with a frame token that is > the main frame token submitted.
 TEST_F(FrameSequenceTrackerTest, MainThreadPresentWithNonMatchedToken) {
-  const char sequence[] = "b(1)B(0,1)E(1)s(1)S(1)e(1,0)b(2)s(2)S(1)e(2,1)P(2)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)e(1,0)b(2)e(2,1)P(2)";
   GenerateSequence(sequence);
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_expected(), 1u);
+  EXPECT_EQ(frames_produced(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, CoalescedMainThreadPresent) {
-  const char sequence[] =
-      "b(1)B(0,1)E(1)s(1)S(1)e(1,1)b(2)B(1,2)E(2)s(2)S(2)e(2,2)P(2)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)e(1,1)b(2)e(2,2)D(1)P(2)";
   GenerateSequence(sequence);
-  EXPECT_EQ(MainThroughput().frames_expected, 2u);
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_expected(), 2u);
+  EXPECT_EQ(frames_produced(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, MainThreadPresentWithNullTimeStamp) {
-  const char sequence[] = "b(1)B(0,1)E(1)s(1)S(1)e(1,1)";
+  CreateNewTracker(FrameInfo::SmoothEffectDrivingThread::kMain);
+  const char sequence[] = "b(1)e(1,1)D(1)";
   GenerateSequence(sequence);
-  collection_.NotifyFramePresented(
-      1, {base::TimeTicks(), viz::BeginFrameArgs::DefaultInterval(),
-          gfx::PresentationFeedback::kFailure});
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  EXPECT_EQ(frames_expected(), 1u);
   // No presentation, no main frame produced.
-  EXPECT_EQ(MainThroughput().frames_produced, 0u);
-  GenerateSequence("b(2)s(2)S(1)e(2,0)P(2)");
-  EXPECT_EQ(MainThroughput().frames_expected, 1u);
+  EXPECT_EQ(frames_produced(), 0u);
+  GenerateSequence("b(2)e(2,0)P(2)");
+  // We are creating a second frame, it will be expected
+  EXPECT_EQ(frames_expected(), 2u);
   // The main frame update is caught up here.
-  EXPECT_EQ(MainThroughput().frames_produced, 1u);
+  EXPECT_EQ(frames_produced(), 1u);
 }
 
 TEST_F(FrameSequenceTrackerTest, TrackerTypeEncoding) {
@@ -894,8 +715,6 @@
   EXPECT_EQ(1u, NumberOfCustomTrackers());
 
   // No reports.
-  uint32_t frame_token = 1u;
-  collection_.NotifyFramePresented(frame_token, {});
   EXPECT_EQ(0u, results.size());
 
   // Start custom tracker 2 and 3 in addition to 1.
@@ -904,7 +723,6 @@
   EXPECT_EQ(3u, NumberOfCustomTrackers());
 
   // All custom trackers are running. No reports.
-  collection_.NotifyFramePresented(frame_token, {});
   EXPECT_EQ(0u, results.size());
 
   // Tracker 2 is stopped and scheduled to terminate.
@@ -912,12 +730,11 @@
   EXPECT_EQ(2u, NumberOfCustomTrackers());
 
   // Tracker 2 has zero expected frames.
-  collection_.NotifyFramePresented(frame_token, {});
   EXPECT_EQ(1u, results.size());
   EXPECT_EQ(0u, results[2].frames_expected_v3);
 
   // Simple sequence of one frame.
-  const char sequence[] = "b(1)B(0,1)s(1)S(1)e(1,0)P(1)";
+  const char sequence[] = "b(1)e(1,0)P(1)";
   GenerateSequence(sequence);
 
   // Stop all custom trackers.
@@ -926,7 +743,6 @@
   EXPECT_EQ(0u, NumberOfCustomTrackers());
 
   // Tracker 1 and 3 and should report.
-  collection_.NotifyFramePresented(frame_token, {});
   EXPECT_EQ(3u, results.size());
   EXPECT_EQ(0u, results[1].frames_dropped_v3);
   EXPECT_EQ(1u, results[1].frames_expected_v3);
diff --git a/cc/metrics/jank_metrics.cc b/cc/metrics/jank_metrics.cc
deleted file mode 100644
index c8ce4e8..0000000
--- a/cc/metrics/jank_metrics.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/metrics/jank_metrics.h"
-
-#include <algorithm>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/metrics/histogram.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/notreached.h"
-#include "base/strings/strcat.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/metrics/frame_sequence_tracker.h"
-
-namespace cc {
-
-namespace {
-
-constexpr uint64_t kMaxNoUpdateFrameQueueLength = 100;
-constexpr int kBuiltinSequenceNum =
-    static_cast<int>(FrameSequenceTrackerType::kMaxType) + 1;
-constexpr int kMaximumStaleHistogramIndex = kBuiltinSequenceNum;
-
-constexpr base::TimeDelta kStaleHistogramMin = base::Microseconds(1);
-constexpr base::TimeDelta kStaleHistogramMax = base::Milliseconds(1000);
-constexpr int kStaleHistogramBucketCount = 200;
-
-constexpr bool IsValidJankThreadType(
-    FrameInfo::SmoothEffectDrivingThread type) {
-  return type == FrameInfo::SmoothEffectDrivingThread::kCompositor ||
-         type == FrameInfo::SmoothEffectDrivingThread::kMain;
-}
-
-int GetIndexForStaleMetric(FrameSequenceTrackerType type) {
-  return static_cast<int>(type);
-}
-
-std::string GetStaleHistogramName(FrameSequenceTrackerType type) {
-  return base::StrCat(
-      {"Graphics.Smoothness.Stale.",
-       FrameSequenceTracker::GetFrameSequenceTrackerTypeName(type)});
-}
-
-std::string GetMaxStaleHistogramName(FrameSequenceTrackerType type) {
-  return base::StrCat(
-      {"Graphics.Smoothness.MaxStale.",
-       FrameSequenceTracker::GetFrameSequenceTrackerTypeName(type)});
-}
-
-}  // namespace
-
-JankMetrics::JankMetrics(FrameSequenceTrackerType tracker_type,
-                         FrameInfo::SmoothEffectDrivingThread effective_thread)
-    : tracker_type_(tracker_type), effective_thread_(effective_thread) {
-  DCHECK(IsValidJankThreadType(effective_thread));
-}
-JankMetrics::~JankMetrics() = default;
-
-void JankMetrics::AddSubmitFrame(uint32_t frame_token,
-                                 uint32_t sequence_number) {
-  // When a frame is submitted, record its |frame_token| and its associated
-  // |sequence_number|. This pushed item will be removed when this frame is
-  // presented.
-  queue_frame_token_and_id_.push({frame_token, sequence_number});
-}
-
-void JankMetrics::AddFrameWithNoUpdate(uint32_t sequence_number,
-                                       base::TimeDelta frame_interval) {
-  DCHECK_LE(queue_frame_id_and_interval_.size(), kMaxNoUpdateFrameQueueLength);
-
-  // If a frame does not cause an increase in expected frames, it will be
-  // recorded here and later subtracted from the presentation interval that
-  // includes this frame.
-  queue_frame_id_and_interval_.push({sequence_number, frame_interval});
-
-  // This prevents the no-update frame queue from growing infinitely on an idle
-  // page.
-  if (queue_frame_id_and_interval_.size() > kMaxNoUpdateFrameQueueLength)
-    queue_frame_id_and_interval_.pop();
-}
-
-void JankMetrics::AddPresentedFrame(
-    uint32_t presented_frame_token,
-    base::TimeTicks current_presentation_timestamp,
-    base::TimeDelta frame_interval) {
-  uint32_t presented_frame_id = 0;
-
-  // Find the main_sequence_number of the presented_frame_token
-  while (!queue_frame_token_and_id_.empty()) {
-    auto token_and_id = queue_frame_token_and_id_.front();
-
-    if (token_and_id.first > presented_frame_token) {
-      // The submitting of this presented frame was not recorded (e.g. the
-      // submitting might have occurred before JankMetrics starts recording).
-      // In that case, do not use this frame presentation for jank detection.
-      return;
-    }
-    queue_frame_token_and_id_.pop();
-
-    if (token_and_id.first == presented_frame_token) {
-      // Found information about the submit of this presented frame;
-      // retrieve the frame's sequence number.
-      presented_frame_id = token_and_id.second;
-      break;
-    }
-  }
-  // If for any reason the sequence number associated with the
-  // presented_frame_token cannot be identified, then ignore this frame
-  // presentation.
-  if (presented_frame_id == 0)
-    return;
-
-  base::TimeDelta no_update_time;  // The frame time spanned by the frames that
-                                   // have no updates
-
-  // If |queue_frame_id_and_interval_| contains an excessive amount of no-update
-  // frames, it indicates that the current presented frame is most likely the
-  // first presentation after a long idle period. Such frames are excluded from
-  // jank/stale calculation because they usually have little impact on
-  // smoothness perception, and |queue_frame_id_and_interval_| does not hold
-  // enough data to accurately estimate the effective frame delta.
-  bool will_ignore_current_frame =
-      queue_frame_id_and_interval_.size() == kMaxNoUpdateFrameQueueLength;
-
-  // Compute the presentation delay contributed by no-update frames that
-  // began BEFORE (i.e. have smaller sequence number than) the current
-  // presented frame.
-  while (!queue_frame_id_and_interval_.empty() &&
-         queue_frame_id_and_interval_.front().first < presented_frame_id) {
-    auto id_and_interval = queue_frame_id_and_interval_.front();
-    if (id_and_interval.first >= last_presentation_frame_id_) {
-      // Only count no-update frames that began SINCE (i.e. have a greater [or
-      // equal] sequence number than) the beginning of previous presented frame.
-      // If, in rare cases, there are still no-update frames that began BEFORE
-      // the beginning of previous presented frame left in the queue, those
-      // frames will simply be discarded and not counted into |no_update_time|.
-      no_update_time += id_and_interval.second;
-    }
-    queue_frame_id_and_interval_.pop();
-  }
-
-  // Exclude the presentation delay introduced by no-update frames. If this
-  // exclusion results in negative frame delta, treat the frame delta as 0.
-  const base::TimeDelta zero_delta = base::Milliseconds(0);
-
-  // Setting the current_frame_delta to zero conveniently excludes the current
-  // frame to be ignored from jank/stale calculation.
-  base::TimeDelta current_frame_delta = (will_ignore_current_frame)
-                                            ? zero_delta
-                                            : current_presentation_timestamp -
-                                                  last_presentation_timestamp_ -
-                                                  no_update_time;
-
-  // Guard against the situation when the physical presentation interval is
-  // shorter than |no_update_time|. For example, consider two BeginFrames A and
-  // B separated by 5 vsync cycles of no-updates (i.e. |no_update_time| = 5
-  // vsync cycles); the Presentation of A occurs 2 vsync cycles after BeginFrame
-  // A, whereas Presentation B occurs in the same vsync cycle as BeginFrame B.
-  // In this situation, the physical presentation interval is shorter than 5
-  // vsync cycles and will result in a negative |current_frame_delta|.
-  if (current_frame_delta < zero_delta)
-    current_frame_delta = zero_delta;
-
-  // Only start tracking jank if this function has already been
-  // called at least once (so that |last_presentation_timestamp_|
-  // and |prev_frame_delta_| have been set).
-  //
-  // The presentation interval is typically a multiple of VSync
-  // intervals (i.e. 16.67ms, 33.33ms, 50ms ... on a 60Hz display)
-  // with small fluctuations. The 0.5 * |frame_interval| criterion
-  // is chosen so that the jank detection is robust to those
-  // fluctuations.
-  if (!last_presentation_timestamp_.is_null()) {
-    base::TimeDelta staleness = current_frame_delta - frame_interval;
-    if (staleness < zero_delta)
-      staleness = zero_delta;
-
-    if (tracker_type_ != FrameSequenceTrackerType::kCustom) {
-      STATIC_HISTOGRAM_POINTER_GROUP(
-          GetStaleHistogramName(tracker_type_),
-          GetIndexForStaleMetric(tracker_type_), kMaximumStaleHistogramIndex,
-          AddTimeMillisecondsGranularity(staleness),
-          base::Histogram::FactoryTimeGet(
-              GetStaleHistogramName(tracker_type_), kStaleHistogramMin,
-              kStaleHistogramMax, kStaleHistogramBucketCount,
-              base::HistogramBase::kUmaTargetedHistogramFlag));
-      if (staleness > max_staleness_)
-        max_staleness_ = staleness;
-    }
-
-    if (!prev_frame_delta_.is_zero() &&
-        current_frame_delta > prev_frame_delta_ + 0.5 * frame_interval) {
-      jank_count_++;
-    }
-  }
-  last_presentation_timestamp_ = current_presentation_timestamp;
-  last_presentation_frame_id_ = presented_frame_id;
-  prev_frame_delta_ = current_frame_delta;
-}
-
-void JankMetrics::ReportJankMetrics(int frames_expected) {
-  if (tracker_type_ == FrameSequenceTrackerType::kCustom)
-    return;
-
-  // Report the max staleness metrics
-  STATIC_HISTOGRAM_POINTER_GROUP(
-      GetMaxStaleHistogramName(tracker_type_),
-      GetIndexForStaleMetric(tracker_type_), kMaximumStaleHistogramIndex,
-      AddTimeMillisecondsGranularity(max_staleness_),
-      base::Histogram::FactoryTimeGet(
-          GetMaxStaleHistogramName(tracker_type_), kStaleHistogramMin,
-          kStaleHistogramMax, kStaleHistogramBucketCount,
-          base::HistogramBase::kUmaTargetedHistogramFlag));
-
-  // Reset counts to avoid duplicated reporting.
-  Reset();
-}
-
-void JankMetrics::Reset() {
-  jank_count_ = 0;
-  max_staleness_ = {};
-}
-
-void JankMetrics::Merge(std::unique_ptr<JankMetrics> jank_metrics) {
-  if (jank_metrics) {
-    jank_count_ += jank_metrics->jank_count_;
-    max_staleness_ = std::max(max_staleness_, jank_metrics->max_staleness_);
-  }
-}
-
-}  // namespace cc
diff --git a/cc/metrics/jank_metrics.h b/cc/metrics/jank_metrics.h
deleted file mode 100644
index 09835f8..0000000
--- a/cc/metrics/jank_metrics.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_METRICS_JANK_METRICS_H_
-#define CC_METRICS_JANK_METRICS_H_
-
-#include <memory>
-#include <queue>
-#include <utility>
-
-#include "base/time/time.h"
-#include "cc/metrics/frame_sequence_metrics.h"
-
-namespace cc {
-// This class reports 3 sets of metrics related to janks:
-// - Graphics.Smoothness.Jank.*: Percent of frames that have longer
-//                               presentation interval than its previous frame.
-//                               Reports one percentage number per tracker.
-// - Graphics.Smoothness.Stale.*: The difference between the real presentation
-//                                interval and its expected value. Reports one
-//                                TimeDelta per frame.
-// - Graphics.Smoothness.MaxStale.*: The maximum staleness value that occurred
-//                                   during the course of an interaction.
-//                                   Reports one TimeDelta per tracker.
-class CC_EXPORT JankMetrics {
- public:
-  JankMetrics(FrameSequenceTrackerType tracker_type,
-              FrameInfo::SmoothEffectDrivingThread effective_thread);
-  ~JankMetrics();
-
-  JankMetrics(const JankMetrics&) = delete;
-  JankMetrics& operator=(const JankMetrics&) = delete;
-
-  void AddFrameWithNoUpdate(uint32_t sequence_number,
-                            base::TimeDelta frame_interval);
-
-  // Check if a jank occurs based on the timestamps of recent presentations.
-  // If there is a jank, increment |jank_count_| and log a trace event.
-  // Graphics.Smoothness.Stale.* metrics are reported in this function.
-  void AddPresentedFrame(uint32_t presented_frame_token,
-                         base::TimeTicks current_presentation_timestamp,
-                         base::TimeDelta frame_interval);
-
-  void AddSubmitFrame(uint32_t frame_token, uint32_t sequence_number);
-
-  // Merge the current jank count with a previously unreported jank metrics.
-  void Merge(std::unique_ptr<JankMetrics> jank_metrics);
-
-  // Report Graphics.Smoothness.(Jank|MaxStale).* metrics.
-  void ReportJankMetrics(int frames_expected);
-
-  // Reset the internal jank count
-  void Reset();
-
-  int jank_count() const { return jank_count_; }
-
-  base::TimeDelta max_staleness() const { return max_staleness_; }
-  FrameInfo::SmoothEffectDrivingThread thread_type() const {
-    return effective_thread_;
-  }
-
- private:
-  // The type of the tracker this JankMetrics object is attached to.
-  const FrameSequenceTrackerType tracker_type_;
-
-  // The thread that contributes to the janks detected by the current
-  // JankMetrics object.
-  const FrameInfo::SmoothEffectDrivingThread effective_thread_;
-
-  // Number of janks detected.
-  int jank_count_ = 0;
-
-  // The time when the last presentation occurs
-  base::TimeTicks last_presentation_timestamp_;
-
-  // The sequence number associated with the last presented frame
-  uint32_t last_presentation_frame_id_ = 0u;
-
-  // The interval before the previous frame presentation.
-  base::TimeDelta prev_frame_delta_;
-
-  // A queue storing {frame token, sequence number} for all submitted
-  // frames, in ascending order of frame token.
-  std::queue<std::pair<uint32_t, uint32_t>> queue_frame_token_and_id_;
-
-  // A queue storing {sequence number, frame interval} of unprocessed no-update
-  // frames, in ascending order of sequence number.
-  std::queue<std::pair<uint32_t, base::TimeDelta>> queue_frame_id_and_interval_;
-
-  // The maximum frame staleness that occurred during the tracker's lifetime.
-  base::TimeDelta max_staleness_;
-};
-
-}  // namespace cc
-
-#endif  // CC_METRICS_JANK_METRICS_H_
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 9998a0338..2516ed1 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -214,11 +214,6 @@
     test_hooks_->WillSendBeginMainFrameOnThread(this);
   }
 
-  void DidSendBeginMainFrame(const viz::BeginFrameArgs& args) override {
-    LayerTreeHostImpl::DidSendBeginMainFrame(args);
-    test_hooks_->DidSendBeginMainFrameOnThread(this);
-  }
-
   void BeginMainFrameAborted(
       CommitEarlyOutReason reason,
       std::vector<std::unique_ptr<SwapPromise>> swap_promises,
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h
index 1cc713a..bb62025 100644
--- a/cc/test/test_hooks.h
+++ b/cc/test/test_hooks.h
@@ -43,7 +43,6 @@
                                           bool has_damage) {}
   virtual void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) {}
   virtual void WillSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) {}
-  virtual void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) {}
   virtual void BeginMainFrameAbortedOnThread(
       LayerTreeHostImpl* host_impl,
       CommitEarlyOutReason reason,
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 26b8d361..4f8a493 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -571,23 +571,12 @@
   return static_cast<const InputHandler&>(*input_delegate_.get());
 }
 
-void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) {
-  frame_trackers_.NotifyBeginMainFrame(args);
-}
-
 void LayerTreeHostImpl::BeginMainFrameAborted(
     CommitEarlyOutReason reason,
     std::vector<std::unique_ptr<SwapPromise>> swap_promises,
     const viz::BeginFrameArgs& args,
     bool next_bmf,
     bool scroll_and_viewport_changes_synced) {
-  if (reason == CommitEarlyOutReason::kAbortedNotVisible ||
-      reason == CommitEarlyOutReason::kFinishedNoUpdates) {
-    frame_trackers_.NotifyMainFrameCausedNoDamage(args, true);
-  } else {
-    frame_trackers_.NotifyMainFrameProcessed(args);
-  }
-
   // If the begin frame data was handled, then scroll and scale set was applied
   // by the main thread, so the active tree needs to be updated as if these sent
   // values were applied and committed.
@@ -619,7 +608,6 @@
     bool scroll_and_viewport_changes_synced,
     const BeginMainFrameMetrics* begin_main_frame_metrics,
     bool commit_timeout) {
-  frame_trackers_.NotifyMainFrameProcessed(commit_args);
   if (!is_measuring_smoothness_ &&
       ((begin_main_frame_metrics &&
         begin_main_frame_metrics->should_measure_smoothness) ||
@@ -2517,10 +2505,6 @@
 
   if (frame->has_no_damage) {
     DCHECK(!resourceless_software_draw_);
-
-    frame_trackers_.NotifyImplFrameCausedNoDamage(frame->begin_frame_ack);
-    frame_trackers_.NotifyMainFrameCausedNoDamage(
-        frame->origin_begin_main_frame_args, false);
     TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD);
     active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
     active_tree()->ResetAllChangeTracking();
@@ -2583,15 +2567,6 @@
   }
 #endif
 
-  // In some cases (e.g. for android-webviews), the frame-submission happens
-  // outside of begin-impl frame pipeline. Avoid notifying the trackers in such
-  // cases.
-  if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
-    frame_trackers_.NotifySubmitFrame(frame_token, frame->has_missing_content,
-                                      frame->begin_frame_ack,
-                                      frame->origin_begin_main_frame_args);
-  }
-
   if (!mutator_host_->NextFrameHasPendingRAF())
     frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF);
   if (!mutator_host_->HasCanvasInvalidation())
@@ -3087,24 +3062,6 @@
                                            FrameSkippedReason reason) {
   if (layer_tree_frame_sink_)
     layer_tree_frame_sink_->DidNotProduceFrame(ack, reason);
-
-  // If a frame was not submitted because there was no damage, or the scheduler
-  // hit the frame-deadline while waiting for the main-thread, notify the
-  // trackers.
-  if (reason != FrameSkippedReason::kRecoverLatency &&
-      impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) {
-    // It is possible that |ack| is for a 'future frame', i.e. for the next
-    // frame from the one currently being handled by the compositor (represented
-    // by the BeginFrameArgs instance in |current_begin_frame_tracker_|). This
-    // can happen, for example, when a frame is skipped early for
-    // latency-recovery, while the previous frame is still being processed.
-    // Notify the trackers only when this is *not* the case (since the trackers
-    // are not notified about the start of the future frame either).
-    const auto& args = current_begin_frame_tracker_.Current();
-    if (args.frame_id == ack.frame_id) {
-      frame_trackers_.NotifyImplFrameCausedNoDamage(ack);
-    }
-  }
 }
 
 void LayerTreeHostImpl::SynchronouslyInitializeAllTiles() {
@@ -5250,8 +5207,6 @@
     uint32_t frame_token,
     std::vector<PresentationTimeCallbackBuffer::SuccessfulCallback> callbacks,
     const viz::FrameTimingDetails& details) {
-  frame_trackers_.NotifyFramePresented(frame_token,
-                                       details.presentation_feedback);
   for (auto& callback : callbacks)
     std::move(callback).Run(details.presentation_feedback.timestamp);
 }
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 184a260..9da3214 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -324,7 +324,6 @@
   }
 
   virtual void WillSendBeginMainFrame() {}
-  virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args);
   virtual void BeginMainFrameAborted(
       CommitEarlyOutReason reason,
       std::vector<std::unique_ptr<SwapPromise>> swap_promises,
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 1f89bb53..8923806 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -3950,11 +3950,9 @@
     // OnNeedsBeginFrames(true) will be called during tree initialization.
   }
 
-  void WillBeginMainFrame() override { ++will_begin_main_frame_count_; }
-
-  void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
-    ++sent_begin_main_frame_count_;
-    EXPECT_GE(begin_frame_count_, sent_begin_main_frame_count_);
+  void WillBeginMainFrame() override {
+    ++will_begin_main_frame_count_;
+    EXPECT_GE(begin_frame_count_, will_begin_main_frame_count_);
   }
 
   void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
@@ -3965,7 +3963,7 @@
   }
 
   void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_LE(sent_begin_main_frame_count_, begin_frame_count_);
+    EXPECT_LE(will_begin_main_frame_count_, begin_frame_count_);
     if (begin_frame_count_ < 3) {
       // Send another animation_only BeginFrame.
       PostIssueBeginFrame(true);
@@ -4000,7 +3998,7 @@
 
     // Fourth BeginMainFrame should lead to commit.
     EXPECT_EQ(5, begin_frame_count_);
-    EXPECT_EQ(3, sent_begin_main_frame_count_);
+    EXPECT_EQ(3, will_begin_main_frame_count_);
 
     EndTest();
   }
@@ -4012,7 +4010,6 @@
   void AfterTest() override {
     EXPECT_EQ(2, commit_count_);
     EXPECT_EQ(5, begin_frame_count_);
-    EXPECT_EQ(3, sent_begin_main_frame_count_);
 
     EXPECT_EQ(3, will_begin_main_frame_count_);
     EXPECT_EQ(3, update_layer_tree_host_count_);
@@ -4036,7 +4033,6 @@
       viz::BeginFrameArgs::kStartingFrameNumber;
   int commit_count_ = 0;
   int begin_frame_count_ = 0;
-  int sent_begin_main_frame_count_ = 0;
   int will_begin_main_frame_count_ = 0;
   int update_layer_tree_host_count_ = 0;
   int ready_to_commit_count_ = 0;
diff --git a/cc/trees/layer_tree_host_unittest_scroll.cc b/cc/trees/layer_tree_host_unittest_scroll.cc
index f86cb9e0..56e63829 100644
--- a/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -2539,7 +2539,7 @@
     invalidated_on_impl_thread_ = false;
   }
 
-  void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
+  void WillSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
     switch (++num_of_main_frames_) {
       case 1:
         // Do nothing for the first BeginMainFrame.
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc
index a398452..0fcf021 100644
--- a/cc/trees/proxy_impl.cc
+++ b/cc/trees/proxy_impl.cc
@@ -732,7 +732,6 @@
       FROM_HERE,
       base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_,
                      std::move(begin_main_frame_state)));
-  host_impl_->DidSendBeginMainFrame(args);
   devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_);
 }
 
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index aec81a9..edb81b6 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -997,7 +997,6 @@
   task_runner_provider_->MainThreadTaskRunner()->PostTask(
       FROM_HERE, base::BindOnce(&SingleThreadProxy::BeginMainFrame,
                                 weak_factory_.GetWeakPtr(), begin_frame_args));
-  host_impl_->DidSendBeginMainFrame(begin_frame_args);
 }
 
 void SingleThreadProxy::FrameIntervalUpdated(base::TimeDelta interval) {
diff --git a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
index 3602323..dcb18bd 100644
--- a/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
+++ b/third_party/blink/renderer/platform/graphics/video_frame_submitter.cc
@@ -381,10 +381,6 @@
       if (presentation_failure) {
         final_state = cc::FrameInfo::FrameFinalState::kDropped;
       } else {
-        frame_trackers_.NotifyFramePresented(
-            frame_token,
-            gfx::PresentationFeedback(feedback.timestamp, feedback.interval,
-                                      feedback.flags));
         final_state = cc::FrameInfo::FrameFinalState::kPresentedAll;
 
         // We assume that presentation feedback is reliable if
@@ -426,7 +422,6 @@
   viz::BeginFrameAck current_begin_frame_ack(args, false);
   if (args.type == viz::BeginFrameArgs::MISSED || !is_rendering_) {
     compositor_frame_sink_->DidNotProduceFrame(current_begin_frame_ack);
-    frame_trackers_.NotifyImplFrameCausedNoDamage(current_begin_frame_ack);
     frame_sorter_.AddFrameResult(
         args,
         CreateFrameInfo(cc::FrameInfo::FrameFinalState::kNoUpdateDesired));
@@ -441,7 +436,6 @@
                                     args.frame_time + args.interval,
                                     args.frame_time + 2 * args.interval)) {
     compositor_frame_sink_->DidNotProduceFrame(current_begin_frame_ack);
-    frame_trackers_.NotifyImplFrameCausedNoDamage(current_begin_frame_ack);
     frame_sorter_.AddFrameResult(
         args,
         CreateFrameInfo(cc::FrameInfo::FrameFinalState::kNoUpdateDesired));
@@ -453,7 +447,6 @@
   auto video_frame = video_frame_provider_->GetCurrentFrame();
   if (!SubmitFrame(current_begin_frame_ack, std::move(video_frame))) {
     compositor_frame_sink_->DidNotProduceFrame(current_begin_frame_ack);
-    frame_trackers_.NotifyImplFrameCausedNoDamage(current_begin_frame_ack);
     frame_sorter_.AddFrameResult(
         args,
         CreateFrameInfo(cc::FrameInfo::FrameFinalState::kNoUpdateDesired));
@@ -719,8 +712,6 @@
   compositor_frame_sink_->SubmitCompositorFrame(
       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
       std::move(compositor_frame), absl::nullopt, 0);
-  frame_trackers_.NotifySubmitFrame(frame_token, false, begin_frame_ack,
-                                    last_begin_frame_args_);
   resource_provider_->ReleaseFrameResources();
 
   waiting_for_compositor_ack_ = true;
@@ -747,8 +738,6 @@
   compositor_frame_sink_->SubmitCompositorFrame(
       child_local_surface_id_allocator_.GetCurrentLocalSurfaceId(),
       std::move(compositor_frame), absl::nullopt, 0);
-  frame_trackers_.NotifySubmitFrame(frame_token, false, begin_frame_ack,
-                                    last_begin_frame_args_);
 
   // We don't set |waiting_for_compositor_ack_| here since we want to allow a
   // subsequent real frame to replace it at any time if needed.
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml
index 2af9107..548c315 100644
--- a/tools/metrics/histograms/metadata/compositing/histograms.xml
+++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -1264,29 +1264,6 @@
   </summary>
 </histogram>
 
-<histogram name="Graphics.Smoothness.MaxStale" units="ms"
-    expires_after="2024-07-21">
-  <owner>jonross@chromium.org</owner>
-  <owner>mjzhang@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Tracks the maximum staleness value for all presentations for a particular
-    sequence of frames (e.g. during scroll, animation, etc.). This is reported
-    in various sub-metrics with suffixes describing the type of the sequence
-    (e.g. TouchScroll etc.).
-
-    Typically, a frame presentation is expected to last at least one vsync
-    cycle, plus any number of additional vsync cycles if no updates are expected
-    duration that time. If the presentation interval is prolonged due to reasons
-    other than listed above, then that prolonged portion will be considered
-    staleness for that frame.
-
-    Note that this metric is reported only when there are sufficient number of
-    frames (&gt;= 100). If there are sequences with fewer frames, then these are
-    aggregated until there are enough frames to produce the metric.
-  </summary>
-</histogram>
-
 <histogram name="Graphics.Smoothness.PercentDroppedFrames3.AllSequences"
     units="%" expires_after="never">
 <!-- expires-never: guiding metric (internal: go/chrome-browser-guiding-metrics) -->
@@ -1347,28 +1324,6 @@
   <token key="Sequence" variants="SmoothnessSequence"/>
 </histogram>
 
-<histogram name="Graphics.Smoothness.Stale" units="ms"
-    expires_after="2024-07-21">
-  <owner>jonross@chromium.org</owner>
-  <owner>mjzhang@chromium.org</owner>
-  <owner>graphics-dev@chromium.org</owner>
-  <summary>
-    Tracks the staleness value for each frame presentation for a particular
-    sequence of frames (e.g. during scroll, animation, etc.). This is reported
-    in various sub-metrics with suffixes describing the type of the sequence
-    (e.g. TouchScroll etc.).
-
-    Typically, a frame presentation is expected to last at least one vsync
-    cycle, plus any number of additional vsync cycles if no updates are expected
-    duration that time. If the presentation interval is prolonged due to reasons
-    other than listed above, then that prolonged portion will be considered
-    staleness.
-
-    Note that the reporting of this metric occurs as soon as a frame is
-    presented, and is not affected by the length of the frame sequence.
-  </summary>
-</histogram>
-
 </histograms>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index f01e65f5..3e915a4 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -4203,21 +4203,6 @@
       name="SmartLock.Performance.StartScanToReceiveFirstRemoteStatusDuration.Unlock"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="SmoothnessSequenceTypes" separator=".">
-  <suffix name="CanvasAnimation" label="Main-thread canvas animation"/>
-  <suffix name="CompositorAnimation" label="Compositor-driven animation"/>
-  <suffix name="JSAnimation" label="JS-driven animation"/>
-  <suffix name="MainThreadAnimation" label="Main-thread driven animation"/>
-  <suffix name="PinchZoom" label="Pinch-to-zoom interaction"/>
-  <suffix name="RAF" label="rAF callback driven animation"/>
-  <suffix name="ScrollbarScroll" label="Scrollbar driven scrolls"/>
-  <suffix name="TouchScroll" label="Touchscreen driven interaction"/>
-  <suffix name="Video" label="Video playback"/>
-  <suffix name="WheelScroll" label="Mousewheel driven interaction"/>
-  <affected-histogram name="Graphics.Smoothness.MaxStale"/>
-  <affected-histogram name="Graphics.Smoothness.Stale"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="Spellcheck_Windows_LocaleSupportType" separator=".">
   <suffix name="Both"
       label="This variation counts the number of locales that are supported