tp: delete experimental_counter_dur

This is no longer necessary with the modern usage of counters.

Change-Id: I2faf9718c3329ee27384e2d907c78b7f2d178635
diff --git a/Android.bp b/Android.bp
index 73f09eb..8ab1fa9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13480,7 +13480,6 @@
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/descendant.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/dfs_weight_bounded.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_annotated_stack.cc",
-        "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flamegraph.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flat_slice.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout.cc",
@@ -13540,7 +13539,6 @@
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/ancestor_unittest.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/connected_flow_unittest.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/descendant_unittest.cc",
-        "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur_unittest.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flat_slice_unittest.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout_unittest.cc",
     ],
diff --git a/BUILD b/BUILD
index 1edf3ce..021c0a3 100644
--- a/BUILD
+++ b/BUILD
@@ -2923,8 +2923,6 @@
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/dfs_weight_bounded.h",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_annotated_stack.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_annotated_stack.h",
-        "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.cc",
-        "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flamegraph.cc",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flamegraph.h",
         "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flat_slice.cc",
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn b/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
index fb11367..3853faa 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
@@ -29,8 +29,6 @@
     "dfs_weight_bounded.h",
     "experimental_annotated_stack.cc",
     "experimental_annotated_stack.h",
-    "experimental_counter_dur.cc",
-    "experimental_counter_dur.h",
     "experimental_flamegraph.cc",
     "experimental_flamegraph.h",
     "experimental_flat_slice.cc",
@@ -94,7 +92,6 @@
     "ancestor_unittest.cc",
     "connected_flow_unittest.cc",
     "descendant_unittest.cc",
-    "experimental_counter_dur_unittest.cc",
     "experimental_flat_slice_unittest.cc",
     "experimental_slice_layout_unittest.cc",
   ]
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.cc b/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.cc
deleted file mode 100644
index 48407cc..0000000
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h"
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <unordered_map>
-#include <vector>
-
-#include "perfetto/base/logging.h"
-#include "perfetto/ext/base/status_or.h"
-#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/db/column_storage.h"
-#include "src/trace_processor/db/table.h"
-#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/tables_py.h"
-#include "src/trace_processor/storage/trace_storage.h"
-#include "src/trace_processor/tables/counter_tables_py.h"
-
-namespace perfetto::trace_processor {
-namespace tables {
-
-ExperimentalCounterDurTable::~ExperimentalCounterDurTable() = default;
-
-}  // namespace tables
-
-ExperimentalCounterDur::ExperimentalCounterDur(
-    const tables::CounterTable& table)
-    : counter_table_(&table) {}
-ExperimentalCounterDur::~ExperimentalCounterDur() = default;
-
-Table::Schema ExperimentalCounterDur::CreateSchema() {
-  return tables::ExperimentalCounterDurTable::ComputeStaticSchema();
-}
-
-std::string ExperimentalCounterDur::TableName() {
-  return tables::ExperimentalCounterDurTable::Name();
-}
-
-uint32_t ExperimentalCounterDur::EstimateRowCount() {
-  return counter_table_->row_count();
-}
-
-base::StatusOr<std::unique_ptr<Table>> ExperimentalCounterDur::ComputeTable(
-    const std::vector<SqlValue>& arguments) {
-  PERFETTO_CHECK(arguments.empty());
-  if (!counter_dur_table_) {
-    counter_dur_table_ = tables::ExperimentalCounterDurTable::ExtendParent(
-        *counter_table_, ComputeDurColumn(*counter_table_),
-        ComputeDeltaColumn(*counter_table_));
-  }
-  return std::make_unique<Table>(counter_dur_table_->Copy());
-}
-
-// static
-ColumnStorage<int64_t> ExperimentalCounterDur::ComputeDurColumn(
-    const CounterTable& table) {
-  // Keep track of the last seen row for each track id.
-  std::unordered_map<TrackId, CounterTable::RowNumber> last_row_for_track_id;
-  ColumnStorage<int64_t> dur;
-
-  for (auto table_it = table.IterateRows(); table_it; ++table_it) {
-    // Check if we already have a previous row for the current track id.
-    TrackId track_id = table_it.track_id();
-    auto it = last_row_for_track_id.find(track_id);
-    if (it == last_row_for_track_id.end()) {
-      // This means we don't have any row - start tracking this row for the
-      // future.
-      last_row_for_track_id.emplace(track_id, table_it.row_number());
-    } else {
-      // This means we have an previous row for the current track id. Update
-      // the duration of the previous row to be up to the current ts.
-      CounterTable::RowNumber old_row = it->second;
-      it->second = table_it.row_number();
-      dur.Set(old_row.row_number(),
-              table_it.ts() - old_row.ToRowReference(table).ts());
-    }
-    // Append -1 to mark this event as not having been finished. On a later
-    // row, we may set this to have the correct value.
-    dur.Append(-1);
-  }
-  return dur;
-}
-
-// static
-ColumnStorage<double> ExperimentalCounterDur::ComputeDeltaColumn(
-    const CounterTable& table) {
-  // Keep track of the last seen row for each track id.
-  std::unordered_map<TrackId, CounterTable::RowNumber> last_row_for_track_id;
-  ColumnStorage<double> delta;
-
-  for (auto table_it = table.IterateRows(); table_it; ++table_it) {
-    // Check if we already have a previous row for the current track id.
-    TrackId track_id = table_it.track_id();
-    auto it = last_row_for_track_id.find(track_id);
-    if (it == last_row_for_track_id.end()) {
-      // This means we don't have any row - start tracking this row for the
-      // future.
-      last_row_for_track_id.emplace(track_id, table_it.row_number());
-    } else {
-      // This means we have an previous row for the current track id. Update
-      // the duration of the previous row to be up to the current ts.
-      CounterTable::RowNumber old_row = it->second;
-      it->second = table_it.row_number();
-      delta.Set(old_row.row_number(),
-                table_it.value() - old_row.ToRowReference(table).value());
-    }
-    delta.Append(0);
-  }
-  return delta;
-}
-
-}  // namespace perfetto::trace_processor
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h b/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h
deleted file mode 100644
index 3e1999b..0000000
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_EXPERIMENTAL_COUNTER_DUR_H_
-#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_EXPERIMENTAL_COUNTER_DUR_H_
-
-#include <cstdint>
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "perfetto/ext/base/status_or.h"
-#include "perfetto/trace_processor/basic_types.h"
-#include "src/trace_processor/db/column_storage.h"
-#include "src/trace_processor/db/table.h"
-#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/static_table_function.h"
-#include "src/trace_processor/tables/counter_tables_py.h"
-
-namespace perfetto::trace_processor {
-
-class ExperimentalCounterDur : public StaticTableFunction {
- public:
-  using CounterTable = tables::CounterTable;
-
-  explicit ExperimentalCounterDur(const CounterTable& table);
-  virtual ~ExperimentalCounterDur() override;
-
-  Table::Schema CreateSchema() override;
-  std::string TableName() override;
-  uint32_t EstimateRowCount() override;
-  base::StatusOr<std::unique_ptr<Table>> ComputeTable(
-      const std::vector<SqlValue>& arguments) override;
-
-  // public + static for testing
-  static ColumnStorage<int64_t> ComputeDurColumn(const CounterTable& table);
-  static ColumnStorage<double> ComputeDeltaColumn(const CounterTable& table);
-
- private:
-  const CounterTable* counter_table_ = nullptr;
-  std::unique_ptr<Table> counter_dur_table_;
-};
-
-}  // namespace perfetto::trace_processor
-
-#endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_EXPERIMENTAL_COUNTER_DUR_H_
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur_unittest.cc b/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur_unittest.cc
deleted file mode 100644
index 783c2a0..0000000
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h"
-
-#include <cstdint>
-
-#include "src/trace_processor/containers/string_pool.h"
-#include "src/trace_processor/tables/counter_tables_py.h"
-#include "src/trace_processor/tables/track_tables_py.h"
-#include "test/gtest_and_gmock.h"
-
-namespace perfetto::trace_processor {
-namespace {
-
-tables::CounterTable::Row CounterRow(int64_t ts, uint32_t track_id) {
-  tables::CounterTable::Row row;
-  row.ts = ts;
-  row.track_id = tables::TrackTable::Id{track_id};
-  return row;
-}
-
-TEST(ExperimentalCounterDur, SmokeDur) {
-  StringPool pool;
-  tables::CounterTable table(&pool);
-
-  table.Insert(CounterRow(100 /* ts */, 1 /* track_id */));
-  table.Insert(CounterRow(102 /* ts */, 2 /* track_id */));
-  table.Insert(CounterRow(105 /* ts */, 1 /* track_id */));
-  table.Insert(CounterRow(105 /* ts */, 3 /* track_id */));
-  table.Insert(CounterRow(105 /* ts */, 2 /* track_id */));
-  table.Insert(CounterRow(110 /* ts */, 2 /* track_id */));
-
-  auto dur = ExperimentalCounterDur::ComputeDurColumn(table);
-  ASSERT_EQ(dur.size(), table.row_count());
-
-  ASSERT_EQ(dur.Get(0), 5);
-  ASSERT_EQ(dur.Get(1), 3);
-  ASSERT_EQ(dur.Get(2), -1);
-  ASSERT_EQ(dur.Get(3), -1);
-  ASSERT_EQ(dur.Get(4), 5);
-  ASSERT_EQ(dur.Get(5), -1);
-}
-
-}  // namespace
-}  // namespace perfetto::trace_processor
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py b/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
index f5186d0..0b63b7f 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
@@ -125,16 +125,6 @@
     ],
     parent=STACK_PROFILE_CALLSITE_TABLE)
 
-EXPERIMENTAL_COUNTER_DUR_TABLE = Table(
-    python_module=__file__,
-    class_name="ExperimentalCounterDurTable",
-    sql_name="experimental_counter_dur",
-    columns=[
-        C("dur", CppInt64()),
-        C("delta", CppDouble()),
-    ],
-    parent=COUNTER_TABLE)
-
 EXPERIMENTAL_SLICE_LAYOUT_TABLE = Table(
     python_module=__file__,
     class_name="ExperimentalSliceLayoutTable",
@@ -180,7 +170,6 @@
     DESCENDANT_SLICE_TABLE,
     DFS_WEIGHT_BOUNDED_TABLE,
     EXPERIMENTAL_ANNOTATED_CALLSTACK_TABLE,
-    EXPERIMENTAL_COUNTER_DUR_TABLE,
     EXPERIMENTAL_SLICE_LAYOUT_TABLE,
     TABLE_INFO_TABLE,
 ]
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 01e5de3..88aca5c 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -112,7 +112,6 @@
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/descendant.h"
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/dfs_weight_bounded.h"
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_annotated_stack.h"
-#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_counter_dur.h"
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flamegraph.h"
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_flat_slice.h"
 #include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout.h"
@@ -1060,8 +1059,6 @@
   engine_->RegisterStaticTableFunction(
       std::make_unique<ExperimentalFlamegraph>(&context_));
   engine_->RegisterStaticTableFunction(
-      std::make_unique<ExperimentalCounterDur>(storage->counter_table()));
-  engine_->RegisterStaticTableFunction(
       std::make_unique<ExperimentalSliceLayout>(
           context_.storage->mutable_string_pool(), &storage->slice_table()));
   engine_->RegisterStaticTableFunction(std::make_unique<TableInfo>(
diff --git a/test/data/ui-screenshots/aggregation.test.ts/frametimeline/frame-timeline-aggregation.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/frametimeline/frame-timeline-aggregation.png.sha256
index 542fdb6..f694f5d 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/frametimeline/frame-timeline-aggregation.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/frametimeline/frame-timeline-aggregation.png.sha256
@@ -1 +1 @@
-2e225197a139e83fd47774da100fed0d4f28a0ca6133b44c795f8b55ced663aa
\ No newline at end of file
+476be67ad67952c63eb73b5ad68d96be476f57bc835f826103586a508b522560
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/gpu-counter/gpu-counter-aggregation.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/gpu-counter/gpu-counter-aggregation.png.sha256
index 2d0f4ae..f029dce 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/gpu-counter/gpu-counter-aggregation.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/gpu-counter/gpu-counter-aggregation.png.sha256
@@ -1 +1 @@
-1c8b7c88d3274a4f056b5424b6008e9de7c54f071530198bd005476268d4096a
\ No newline at end of file
+ac5cb189130bd8f57843c3b366ba8a12e1d27848d4722fb541c5405a3ef107d7
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-process.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-process.png.sha256
index 7261bfa..23223bb 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-process.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-process.png.sha256
@@ -1 +1 @@
-bf2ebe5c363e0d6b52275c7a9dac0aa48ff68eee4aab5f2ae3119f31268168c8
\ No newline at end of file
+009ae9d78994c22adaa2484909acd8d2627f61b76573412012e079406cde7253
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-thread.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-thread.png.sha256
index 1822481..db33e76 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-thread.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/sched/cpu-by-thread.png.sha256
@@ -1 +1 @@
-47e800f769fca6c4a47e76b16e7ec4a5e98756caf1dd00e8edb4d41430270255
\ No newline at end of file
+0889c04d6944c1704452294714be35dd1a044bf5eb2e85360d72143ba784b5d7
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-occurrences.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-occurrences.png.sha256
index 2f330aa..21bd7d9 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-occurrences.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-occurrences.png.sha256
@@ -1 +1 @@
-06e80899f56eaee0eef9a7696fb8915466c13af88d2c1aa08003b5ecc6a35904
\ No newline at end of file
+b77e2ef33ad26be6ecd0a8ef71f87c69b488c4162d792f84f5204d4a8c0d95c5
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration-desc.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration-desc.png.sha256
index f80b0f5..ad36d05 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration-desc.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration-desc.png.sha256
@@ -1 +1 @@
-c67f41c1fab11d8f92de7cc96f644dd011840ab6466c120a2dafe7d88c3257dd
\ No newline at end of file
+f77cea1dfa259570c77ac7836adb998217af7c9a650479b6da6673a4d5f08096
\ No newline at end of file
diff --git a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration.png.sha256 b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration.png.sha256
index 9a63cb2..d67923a 100644
--- a/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration.png.sha256
+++ b/test/data/ui-screenshots/aggregation.test.ts/sched/sort-by-wall-duration.png.sha256
@@ -1 +1 @@
-4d6b82127cb8d51ccc7a4eec7821cd75e0e074a4d226a0c3f8c8c2251e089a1f
\ No newline at end of file
+c2e55d4a9f1671e0168637821dba9dbb77e67266cd10b20366084e0790aef290
\ No newline at end of file
diff --git a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks-pivot/debug-track-pivot.png.sha256 b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks-pivot/debug-track-pivot.png.sha256
index dd5fbe0..372ff6b 100644
--- a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks-pivot/debug-track-pivot.png.sha256
+++ b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks-pivot/debug-track-pivot.png.sha256
@@ -1 +1 @@
-d029192977e9cdc606643b27ac6bc6a0d414bb7fe27b0ca6d229514e699af30f
\ No newline at end of file
+1a0f90dd580562e442c7fbbfcdad37f9f9aeeb20d88c66b4f4deaa98e7630744
\ No newline at end of file
diff --git a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-slice-clicked.png.sha256 b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-slice-clicked.png.sha256
index 09701c1..4bb3e55 100644
--- a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-slice-clicked.png.sha256
+++ b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-slice-clicked.png.sha256
@@ -1 +1 @@
-e29d0987d3f465a84d2012a9311aabc09a526bf26807882ec69ade819c225fbe
\ No newline at end of file
+2bbb39c5a1116587f8f511e2d2f346d6052efd796bb446e64f35fa83b34fc631
\ No newline at end of file
diff --git a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-added.png.sha256 b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-added.png.sha256
index e007e64..e532e33 100644
--- a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-added.png.sha256
+++ b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-added.png.sha256
@@ -1 +1 @@
-5670772a88fab2ce938a68e3988719e018d30d7181fc7bb03717c4c5ef3b6747
\ No newline at end of file
+3907851e2b92ceb523d3ceb03b28003dfe7568d8431bf10a4997ca17ef9a6ba0
\ No newline at end of file
diff --git a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-removed.png.sha256 b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-removed.png.sha256
index 033cbb3..6d5456b 100644
--- a/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-removed.png.sha256
+++ b/test/data/ui-screenshots/debug_tracks.test.ts/debug-tracks/debug-track-removed.png.sha256
@@ -1 +1 @@
-9f3dbc332c5a7d0f628d5ae6d72c2e3939cca395c484492d4dc7f7d5abfdd868
\ No newline at end of file
+72287b646e7f912b752c806b84c610aa3188acde481a75b7e779f74825750e23
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tab/ftrace-tab.png.sha256 b/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tab/ftrace-tab.png.sha256
index 1278b23..6248292 100644
--- a/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tab/ftrace-tab.png.sha256
+++ b/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tab/ftrace-tab.png.sha256
@@ -1 +1 @@
-75c74146fa7541ca52dc0995f6f31367740eebb100eb63cabc7e12e2dbc65e77
\ No newline at end of file
+cee4518a2575d9cc929b8ba6c0409f7e7139a47da22ca7e7ab6c7658db275942
\ No newline at end of file
diff --git a/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tracks/ftrace-events.png.sha256 b/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tracks/ftrace-events.png.sha256
index d56456f..0a0b087 100644
--- a/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tracks/ftrace-events.png.sha256
+++ b/test/data/ui-screenshots/ftrace_tracks_and_tab.test.ts/ftrace-tracks/ftrace-events.png.sha256
@@ -1 +1 @@
-d4c0d158b34c5de3e7efd3276e95532e808a850e63d2066d976816375856442c
\ No newline at end of file
+201b85b1dc910a5956674b9a60b45d2bf96eaf0bd1cf25a2a3380c0ae8d1eee4
\ No newline at end of file
diff --git a/test/data/ui-screenshots/load_and_tracks.test.ts/info-and-stats/back-to-timeline.png.sha256 b/test/data/ui-screenshots/load_and_tracks.test.ts/info-and-stats/back-to-timeline.png.sha256
index 137d9d9..c417ca1 100644
--- a/test/data/ui-screenshots/load_and_tracks.test.ts/info-and-stats/back-to-timeline.png.sha256
+++ b/test/data/ui-screenshots/load_and_tracks.test.ts/info-and-stats/back-to-timeline.png.sha256
@@ -1 +1 @@
-3f61a35bd9233e95e926a3ac7115f440fc2ddc6f06abba2f3c6e5dfd3f660d08
\ No newline at end of file
+d34d9a1cdc9f65fafa41b838939ebf13aa408c7bd8d0b2e3bf7f1e4f9f57a9e8
\ No newline at end of file
diff --git a/test/data/ui-screenshots/load_and_tracks.test.ts/load-trace/loaded.png.sha256 b/test/data/ui-screenshots/load_and_tracks.test.ts/load-trace/loaded.png.sha256
index 137d9d9..c417ca1 100644
--- a/test/data/ui-screenshots/load_and_tracks.test.ts/load-trace/loaded.png.sha256
+++ b/test/data/ui-screenshots/load_and_tracks.test.ts/load-trace/loaded.png.sha256
@@ -1 +1 @@
-3f61a35bd9233e95e926a3ac7115f440fc2ddc6f06abba2f3c6e5dfd3f660d08
\ No newline at end of file
+d34d9a1cdc9f65fafa41b838939ebf13aa408c7bd8d0b2e3bf7f1e4f9f57a9e8
\ No newline at end of file
diff --git a/test/data/ui-screenshots/queries.test.ts/omnibox-query/query-mode.png.sha256 b/test/data/ui-screenshots/queries.test.ts/omnibox-query/query-mode.png.sha256
index f1c484d..485cbf4 100644
--- a/test/data/ui-screenshots/queries.test.ts/omnibox-query/query-mode.png.sha256
+++ b/test/data/ui-screenshots/queries.test.ts/omnibox-query/query-mode.png.sha256
@@ -1 +1 @@
-f179d5ce54ecf8372fd29e847a1e96ef052c6bb25438b77c5fa27028b3939cf5
\ No newline at end of file
+ce0814c13403d7b21211cfc068ba152d54c8da03726e1732087f256a30260d09
\ No newline at end of file
diff --git a/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-process.png.sha256 b/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-process.png.sha256
index c3ab244..42d5c45 100644
--- a/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-process.png.sha256
+++ b/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-process.png.sha256
@@ -1 +1 @@
-71b4349dcc1ca82fe0dd4af2f42254a276bcc7d7cc1307ccfcbe1add999359a1
\ No newline at end of file
+84759b08519a616e0be568036aec73a90c603c73992416ef439e6db7d7a0bfc1
\ No newline at end of file
diff --git a/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-thread.png.sha256 b/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-thread.png.sha256
index 0c866f6..8f0c982 100644
--- a/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-thread.png.sha256
+++ b/test/data/ui-screenshots/wattson.test.ts/sched-aggregations/sched-aggr-thread.png.sha256
@@ -1 +1 @@
-8403f026fc523b72ad30a33edcf6413eea7064f37dd1df0d30de92abcdc3d801
\ No newline at end of file
+de4c43ba9570aebf4dfe964cde1802445856ab02812781ff368d4fcb259fb1f2
\ No newline at end of file
diff --git a/test/data/ui-screenshots/wattson.test.ts/wattson-aggregations/wattson-estimate-aggr.png.sha256 b/test/data/ui-screenshots/wattson.test.ts/wattson-aggregations/wattson-estimate-aggr.png.sha256
index fe66d7b..a1ecd5c 100644
--- a/test/data/ui-screenshots/wattson.test.ts/wattson-aggregations/wattson-estimate-aggr.png.sha256
+++ b/test/data/ui-screenshots/wattson.test.ts/wattson-aggregations/wattson-estimate-aggr.png.sha256
@@ -1 +1 @@
-cb910ba8f809c091167d004b209bb17aea2a97a11e30b8023eba306b016bbf27
\ No newline at end of file
+bf940c29825fd4aa44cecc93bf146ee56f0e1013af4267ff5311da40a2b1adb9
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/tables/counter_dur_test.sql b/test/trace_processor/diff_tests/tables/counter_dur_test.sql
deleted file mode 100644
index 67a60b9..0000000
--- a/test/trace_processor/diff_tests/tables/counter_dur_test.sql
+++ /dev/null
@@ -1 +0,0 @@
-SELECT ts, dur FROM experimental_counter_dur WHERE track_id IN (1, 2, 3) ORDER BY dur LIMIT 10;
diff --git a/test/trace_processor/diff_tests/tables/tests_counters.py b/test/trace_processor/diff_tests/tables/tests_counters.py
index d8a6a59..ace4cf9 100644
--- a/test/trace_processor/diff_tests/tables/tests_counters.py
+++ b/test/trace_processor/diff_tests/tables/tests_counters.py
@@ -108,52 +108,6 @@
         """,
         out=Path('filter_row_vector_example_android_trace_30s.out'))
 
-  def test_counter_dur_example_android_trace_30s(self):
-    return DiffTestBlueprint(
-        trace=DataPath('example_android_trace_30s.pb'),
-        query=Path('counter_dur_test.sql'),
-        out=Csv("""
-        "ts","dur"
-        100351738640,-1
-        100351738640,-1
-        100351738640,-1
-        70731059648,19510835
-        70731059648,19510835
-        70731059648,19510835
-        73727335051,23522762
-        73727335051,23522762
-        73727335051,23522762
-        86726132752,24487554
-        """))
-
-  def test_counter_dur_example_android_trace_30s_machine_id(self):
-    return DiffTestBlueprint(
-        trace=DataPath('example_android_trace_30s.pb'),
-        trace_modifier=TraceInjector(
-            ['ftrace_events', 'sys_stats', 'process_stats', 'process_tree'],
-            {'machine_id': 1001}),
-        query="""
-        SELECT ts, dur, m.raw_id as raw_machine_id
-        FROM experimental_counter_dur c
-        JOIN counter_track t on c.track_id = t.id
-        JOIN machine m on t.machine_id = m.id
-        WHERE track_id IN (1, 2, 3)
-        ORDER BY dur LIMIT 10;
-        """,
-        out=Csv("""
-        "ts","dur","raw_machine_id"
-        100351738640,-1,1001
-        100351738640,-1,1001
-        100351738640,-1,1001
-        70731059648,19510835,1001
-        70731059648,19510835,1001
-        70731059648,19510835,1001
-        73727335051,23522762,1001
-        73727335051,23522762,1001
-        73727335051,23522762,1001
-        86726132752,24487554,1001
-        """))
-
   # Tests counter.machine_id and process_counter_track.machine.
   def test_filter_row_vector_example_android_trace_30s_machine_id(self):
     return DiffTestBlueprint(
diff --git a/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts b/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
index 4880341..9811843 100644
--- a/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
+++ b/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
@@ -26,7 +26,11 @@
 import {uuidv4Sql} from '../../base/uuid';
 import {TrackMouseEvent, TrackRenderContext} from '../../public/track';
 import {Point2D} from '../../base/geom';
-import {createView, createVirtualTable} from '../../trace_processor/sql_utils';
+import {
+  createPerfettoTable,
+  createView,
+  createVirtualTable,
+} from '../../trace_processor/sql_utils';
 import {AsyncDisposableStack} from '../../base/disposable_stack';
 import {Trace} from '../../public/trace';
 
@@ -68,6 +72,9 @@
 
   async onCreate() {
     this.trash = new AsyncDisposableStack();
+    await this.trace.engine.query(`
+      INCLUDE PERFETTO MODULE counters.intervals;
+    `);
     if (this.config.idleTrackId === undefined) {
       this.trash.use(
         await createView(
@@ -75,26 +82,32 @@
           `raw_freq_idle_${this.trackUuid}`,
           `
             select ts, dur, value as freqValue, -1 as idleValue
-            from experimental_counter_dur c
-            where track_id = ${this.config.freqTrackId}
+            from counter_leading_intervals!((
+              select id, ts, track_id, value
+              from counter
+              where track_id = ${this.config.freqTrackId}
+            ))
           `,
         ),
       );
     } else {
       this.trash.use(
-        await createView(
+        await createPerfettoTable(
           this.trace.engine,
           `raw_freq_${this.trackUuid}`,
           `
             select ts, dur, value as freqValue
-            from experimental_counter_dur c
-            where track_id = ${this.config.freqTrackId}
+            from counter_leading_intervals!((
+              select id, ts, track_id, value
+              from counter
+             where track_id = ${this.config.freqTrackId}
+            ))
           `,
         ),
       );
 
       this.trash.use(
-        await createView(
+        await createPerfettoTable(
           this.trace.engine,
           `raw_idle_${this.trackUuid}`,
           `
@@ -102,8 +115,11 @@
               ts,
               dur,
               iif(value = 4294967295, -1, cast(value as int)) as idleValue
-            from experimental_counter_dur c
-            where track_id = ${this.config.idleTrackId}
+            from counter_leading_intervals!((
+              select id, ts, track_id, value
+              from counter
+              where track_id = ${this.config.idleTrackId}
+            ))
           `,
         ),
       );
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/counter_selection_aggregator.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/counter_selection_aggregator.ts
index 6a2bd3f..13fb47d 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/counter_selection_aggregator.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/counter_selection_aggregator.ts
@@ -38,27 +38,36 @@
     if (trackIds.length === 1) {
       // Optimized query for the special case where there is only 1 track id.
       query = `CREATE OR REPLACE PERFETTO TABLE ${this.id} AS
-      WITH aggregated AS (
-        SELECT
-          COUNT(1) AS count,
-          ROUND(SUM(
-            (MIN(ts + dur, ${area.end}) - MAX(ts,${area.start}))*value)/${duration},
-            2
-          ) AS avg_value,
-          (SELECT value FROM experimental_counter_dur WHERE track_id = ${trackIds[0]}
-            AND ts + dur >= ${area.start}
-            AND ts <= ${area.end} ORDER BY ts DESC LIMIT 1)
-            AS last_value,
-          (SELECT value FROM experimental_counter_dur WHERE track_id = ${trackIds[0]}
-            AND ts + dur >= ${area.start}
-            AND ts <= ${area.end} ORDER BY ts ASC LIMIT 1)
-            AS first_value,
-          MIN(value) AS min_value,
-          MAX(value) AS max_value
-        FROM experimental_counter_dur
-          WHERE track_id = ${trackIds[0]}
-          AND ts + dur >= ${area.start}
-          AND ts <= ${area.end})
+      WITH
+        res AS (
+          select c.*
+          from counter_leading_intervals!((
+            SELECT counter.*
+            FROM counter
+            WHERE counter.track_id = ${trackIds[0]}
+              AND counter.ts <= ${area.end}
+          )) c
+          WHERE c.ts + c.dur >= ${area.start}
+        ),
+        aggregated AS (
+          SELECT
+            COUNT(1) AS count,
+            ROUND(SUM(
+              (MIN(ts + dur, ${area.end}) - MAX(ts,${area.start}))*value)/${duration},
+              2
+            ) AS avg_value,
+            (SELECT value FROM counter WHERE track_id = ${trackIds[0]}
+              AND ts + dur >= ${area.start}
+              AND ts <= ${area.end} ORDER BY ts DESC LIMIT 1)
+              AS last_value,
+            (SELECT value FROM counter WHERE track_id = ${trackIds[0]}
+              AND ts + dur >= ${area.start}
+              AND ts <= ${area.end} ORDER BY ts ASC LIMIT 1)
+              AS first_value,
+            MIN(value) AS min_value,
+            MAX(value) AS max_value
+          FROM res
+        )
       SELECT
         (SELECT name FROM counter_track WHERE id = ${trackIds[0]}) AS name,
         *,
@@ -68,23 +77,31 @@
     } else {
       // Slower, but general purspose query that can aggregate multiple tracks
       query = `CREATE OR REPLACE PERFETTO TABLE ${this.id} AS
-      WITH aggregated AS (
-        SELECT track_id,
-          COUNT(1) AS count,
-          ROUND(SUM(
-            (MIN(ts + dur, ${area.end}) - MAX(ts,${area.start}))*value)/${duration},
-            2
-          ) AS avg_value,
-          value_at_max_ts(-ts, value) AS first,
-          value_at_max_ts(ts, value) AS last,
-          MIN(value) AS min_value,
-          MAX(value) AS max_value
-        FROM experimental_counter_dur
-          WHERE track_id IN (${trackIds})
-          AND ts + dur >= ${area.start} AND
-          ts <= ${area.end}
-        GROUP BY track_id
-      )
+      WITH
+        res AS (
+          select c.*
+          from counter_leading_intervals!((
+            SELECT counter.*
+            FROM counter
+            WHERE counter.track_id in (${trackIds})
+              AND counter.ts <= ${area.end}
+          )) c
+          where c.ts + c.dur >= ${area.start}
+        ),
+        aggregated AS (
+          SELECT track_id,
+            COUNT(1) AS count,
+            ROUND(SUM(
+              (MIN(ts + dur, ${area.end}) - MAX(ts,${area.start}))*value)/${duration},
+              2
+            ) AS avg_value,
+            value_at_max_ts(-ts, value) AS first,
+            value_at_max_ts(ts, value) AS last,
+            MIN(value) AS min_value,
+            MAX(value) AS max_value
+          FROM res
+          GROUP BY track_id
+        )
       SELECT
         name,
         count,