Merge "Update chrome_scrolls column names to be more accurate." into main
diff --git a/docs/analysis/debug-tracks.md b/docs/analysis/debug-tracks.md
new file mode 100644
index 0000000..e3c973c
--- /dev/null
+++ b/docs/analysis/debug-tracks.md
@@ -0,0 +1,33 @@
+# Debug Tracks
+
+Debug Tracks are a way to display tabular results from running a PerfettoSQL
+query as a new so-called "debug" track. Specifically, if the resultant table can
+be visualised in a slice format (for example, the
+[`slice`](sql-tables.autogen#slice) table), a debug track can be created from
+it.
+
+For a result table to be able to be visualised in a slice format, it should
+include:
+
+1. A name (the name of the slice) column.
+1. A non-null timestamp (the timestamp, in nanoseconds, at the start of the
+ slice) column.
+1. (Optionally) a duration (the duration, in nanoseconds, of the slice) column.
+
+To create a new debug track:
+
+1. Run a SQL query, and ensure its results are `slice`-like (as described
+ above).
+ ![Query for debug track](/docs/images/debug-tracks/debug-tracks-query.png)
+1. Navigate to the Timeline view, and click on "Show debug track" to set up a
+ new debug track. Note that the names of the columns in the result table do
+ not necessarily have to be `name`, `ts`, or `dur`. Columns which
+ *semantically* match but have a different name can be selected from the
+ drop-down selectors.
+ ![Create a new debug track](/docs/images/debug-tracks/debug-tracks-create.png)
+1. The debug track is visible as a pinned track near the top of the Timeline
+ view with slices from the table from which the track was created (note that
+ slices with no/zero duration will be displayed as instant events). The debug
+ track may be manually unpinned and then it should appear on the top of other
+ unpinned tracks.
+ ![Resultant debug track](/docs/images/debug-tracks/debug-tracks-result.png)
diff --git a/docs/images/debug-tracks/debug-tracks-create.png b/docs/images/debug-tracks/debug-tracks-create.png
new file mode 100644
index 0000000..c98b49b
--- /dev/null
+++ b/docs/images/debug-tracks/debug-tracks-create.png
Binary files differ
diff --git a/docs/images/debug-tracks/debug-tracks-query.png b/docs/images/debug-tracks/debug-tracks-query.png
new file mode 100644
index 0000000..99d2029
--- /dev/null
+++ b/docs/images/debug-tracks/debug-tracks-query.png
Binary files differ
diff --git a/docs/images/debug-tracks/debug-tracks-result.png b/docs/images/debug-tracks/debug-tracks-result.png
new file mode 100644
index 0000000..51d6fd2
--- /dev/null
+++ b/docs/images/debug-tracks/debug-tracks-result.png
Binary files differ
diff --git a/docs/toc.md b/docs/toc.md
index eca4ee7..d7c34e3 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -58,6 +58,7 @@
* [Deep linking to Perfetto UI](visualization/deep-linking-to-perfetto-ui.md)
* [Perfetto UI release process](visualization/perfetto-ui-release-process.md)
* [Pivot tables](analysis/pivot-tables.md)
+ * [Debug tracks](analysis/debug-tracks.md)
* [Core concepts](#)
* [Trace configuration](concepts/config.md)
diff --git a/include/perfetto/protozero/message.h b/include/perfetto/protozero/message.h
index 069bc34..efcdf9f 100644
--- a/include/perfetto/protozero/message.h
+++ b/include/perfetto/protozero/message.h
@@ -181,6 +181,8 @@
// The caller needs to guarantee that the appended data is properly
// proto-encoded and each field has a proto preamble.
void AppendRawProtoBytes(const void* data, size_t size) {
+ if (nested_message_)
+ EndNestedMessage();
const uint8_t* src = reinterpret_cast<const uint8_t*>(data);
WriteToStream(src, src + size);
}
diff --git a/perfetto.rc b/perfetto.rc
index c635ac2..2118172 100644
--- a/perfetto.rc
+++ b/perfetto.rc
@@ -20,7 +20,6 @@
user nobody
group nobody
task_profiles ServiceCapacityLow
- priority -10
service traced_probes /system/bin/traced_probes
class late_start
@@ -35,7 +34,6 @@
onrestart exec_background - nobody shell -- /system/bin/traced_probes --cleanup-after-crash
file /dev/kmsg w
capabilities DAC_READ_SEARCH
- priority -10
on property:persist.device_config.global_settings.sys_traced=1
setprop persist.traced.enable 1
diff --git a/protos/perfetto/config/android/surfaceflinger_layers_config.proto b/protos/perfetto/config/android/surfaceflinger_layers_config.proto
index e5ffc0f..0b8d108 100644
--- a/protos/perfetto/config/android/surfaceflinger_layers_config.proto
+++ b/protos/perfetto/config/android/surfaceflinger_layers_config.proto
@@ -27,7 +27,6 @@
// occurs.
MODE_ACTIVE = 1;
- // Default mode (applied by SurfaceFlinger if no mode is specified).
// Generate layers snapshots from the transactions kept in the
// SurfaceFlinger's internal ring buffer.
// The layers snapshots generation occurs when this data source is flushed.
@@ -35,6 +34,11 @@
// Trace a single layers snapshot.
MODE_DUMP = 3;
+
+ // Default mode (applied by SurfaceFlinger if no mode is specified).
+ // Same as MODE_GENERATED, but triggers the layers snapshots generation only when a bugreport
+ // is taken.
+ MODE_GENERATED_BUGREPORT_ONLY = 4;
}
optional Mode mode = 1;
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 99b62de..bf19bbb 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -548,7 +548,6 @@
// occurs.
MODE_ACTIVE = 1;
- // Default mode (applied by SurfaceFlinger if no mode is specified).
// Generate layers snapshots from the transactions kept in the
// SurfaceFlinger's internal ring buffer.
// The layers snapshots generation occurs when this data source is flushed.
@@ -556,6 +555,11 @@
// Trace a single layers snapshot.
MODE_DUMP = 3;
+
+ // Default mode (applied by SurfaceFlinger if no mode is specified).
+ // Same as MODE_GENERATED, but triggers the layers snapshots generation only when a bugreport
+ // is taken.
+ MODE_GENERATED_BUGREPORT_ONLY = 4;
}
optional Mode mode = 1;
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 75043d0..e0ee8d3 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -548,7 +548,6 @@
// occurs.
MODE_ACTIVE = 1;
- // Default mode (applied by SurfaceFlinger if no mode is specified).
// Generate layers snapshots from the transactions kept in the
// SurfaceFlinger's internal ring buffer.
// The layers snapshots generation occurs when this data source is flushed.
@@ -556,6 +555,11 @@
// Trace a single layers snapshot.
MODE_DUMP = 3;
+
+ // Default mode (applied by SurfaceFlinger if no mode is specified).
+ // Same as MODE_GENERATED, but triggers the layers snapshots generation only when a bugreport
+ // is taken.
+ MODE_GENERATED_BUGREPORT_ONLY = 4;
}
optional Mode mode = 1;
diff --git a/python/generators/sql_processing/docs_parse.py b/python/generators/sql_processing/docs_parse.py
index 079a600..8f17b1b 100644
--- a/python/generators/sql_processing/docs_parse.py
+++ b/python/generators/sql_processing/docs_parse.py
@@ -230,14 +230,14 @@
self._validate_only_contains_annotations(doc.annotations, {'@arg', '@ret'})
ret_type, ret_desc = self._parse_ret(doc.annotations, ret)
- name = self._parse_name(upper=True)
+ name = self._parse_name()
if not is_snake_case(name):
self._error('Function name %s is not snake_case (should be %s) ' %
(name, name.casefold()))
return Function(
- name=self._parse_name(upper=True),
+ name=name,
desc=self._parse_desc_not_empty(doc.description),
args=self._parse_args(doc.annotations, args),
return_type=ret_type,
@@ -273,8 +273,14 @@
self._validate_only_contains_annotations(doc.annotations,
{'@arg', '@column'})
+ name = self._parse_name()
+
+ if not is_snake_case(name):
+ self._error('Function name %s is not snake_case (should be %s) ' %
+ (name, name.casefold()))
+
return TableFunction(
- name=self._parse_name(upper=True),
+ name=name,
desc=self._parse_desc_not_empty(doc.description),
cols=self._parse_columns(doc.annotations, columns),
args=self._parse_args(doc.annotations, args),
diff --git a/python/generators/sql_processing/utils.py b/python/generators/sql_processing/utils.py
index 97d7d8f..c701ceb 100644
--- a/python/generators/sql_processing/utils.py
+++ b/python/generators/sql_processing/utils.py
@@ -130,6 +130,12 @@
'Use CREATE PERFETTO FUNCTION instead.\n'
f'Offending file: {path}')
+ if 'create_view_function' in line.casefold():
+ errors.append(
+ 'CREATE_VIEW_FUNCTION is deprecated in trace processor. '
+ 'Use CREATE PERFETTO FUNCTION $name RETURNS TABLE instead.\n'
+ f'Offending file: {path}')
+
if 'import(' in line.casefold():
errors.append('SELECT IMPORT is deprecated in trace processor. '
'Use INCLUDE PERFETTO MODULE instead.\n'
diff --git a/python/test/stdlib_unittest.py b/python/test/stdlib_unittest.py
index d1a90be..479c603 100644
--- a/python/test/stdlib_unittest.py
+++ b/python/test/stdlib_unittest.py
@@ -104,7 +104,7 @@
{ARGS_STR}
{COLS_STR}
SELECT CREATE_VIEW_FUNCTION(
- 'FOO_VIEW_FN({ARGS_SQL_STR})',
+ 'foo_view_fn({ARGS_SQL_STR})',
'{COLS_SQL_STR}',
'{SQL_STR}'
);
@@ -112,7 +112,7 @@
self.assertListEqual(res.errors, [])
fn = res.table_functions[0]
- self.assertEqual(fn.name, 'FOO_VIEW_FN')
+ self.assertEqual(fn.name, 'foo_view_fn')
self.assertEqual(fn.desc, 'First line. Second line.')
self.assertEqual(
fn.args, {
diff --git a/src/protozero/message_unittest.cc b/src/protozero/message_unittest.cc
index 5b3c09f..985ed5c 100644
--- a/src/protozero/message_unittest.cc
+++ b/src/protozero/message_unittest.cc
@@ -236,6 +236,27 @@
EXPECT_EQ("42424242", GetNextSerializedBytes(4));
}
+TEST_F(MessageTest, AppendRawProtoBytesFinalizesNestedMessage) {
+ Message* root_msg = NewMessage();
+
+ uint8_t buffer[42];
+ memset(buffer, 0x42, sizeof(buffer));
+
+ FakeChildMessage* nested_msg =
+ root_msg->BeginNestedMessage<FakeChildMessage>(9001 /* field_id */);
+ nested_msg->AppendVarInt(4 /* field_id */, 2);
+ uint8_t* nested_msg_size_field = nested_msg->size_field();
+
+ EXPECT_FALSE(nested_msg->is_finalized());
+ EXPECT_EQ(0u, *nested_msg_size_field);
+
+ root_msg->AppendRawProtoBytes(buffer, sizeof(buffer));
+
+ // Nested message should have been finalized as a side effect of appending
+ // raw bytes.
+ EXPECT_EQ(0x82u, *nested_msg_size_field);
+}
+
TEST_F(MessageTest, AppendScatteredBytesFinalizesNestedMessage) {
Message* root_msg = NewMessage();
diff --git a/src/trace_processor/metrics/sql/android/android_startup.sql b/src/trace_processor/metrics/sql/android/android_startup.sql
index 5a92db8..d2efb76 100644
--- a/src/trace_processor/metrics/sql/android/android_startup.sql
+++ b/src/trace_processor/metrics/sql/android/android_startup.sql
@@ -43,20 +43,16 @@
-- Returns the slices for forked processes. Never present in hot starts.
-- Prefer this over process start_ts, since the process might have
-- been preforked.
-SELECT CREATE_VIEW_FUNCTION(
- 'ZYGOTE_FORK_FOR_LAUNCH(startup_id INT)',
- 'ts INT, dur INT',
- '
- SELECT slice.ts, slice.dur
- FROM android_startups l
- JOIN slice ON (
- l.ts < slice.ts AND
- slice.ts + slice.dur < l.ts_end AND
- STR_SPLIT(slice.name, ": ", 1) = l.package
- )
- WHERE l.startup_id = $startup_id AND slice.name GLOB "Start proc: *"
- '
-);
+CREATE PERFETTO FUNCTION zygote_fork_for_launch(startup_id INT)
+RETURNS TABLE(ts INT, dur INT) AS
+SELECT slice.ts, slice.dur
+FROM android_startups l
+JOIN slice ON (
+ l.ts < slice.ts AND
+ slice.ts + slice.dur < l.ts_end AND
+ STR_SPLIT(slice.name, ': ', 1) = l.package
+)
+WHERE l.startup_id = $startup_id AND slice.name GLOB 'Start proc: *';
-- Returns the fully drawn slice proto given a launch id.
CREATE PERFETTO FUNCTION report_fully_drawn_for_launch(startup_id INT)
@@ -79,17 +75,14 @@
);
-- Given a launch id and GLOB for a slice name, returns the N longest slice name and duration.
-SELECT CREATE_VIEW_FUNCTION(
- 'GET_LONG_SLICES_FOR_LAUNCH(startup_id INT, slice_name STRING, top_n INT)',
- 'slice_name STRING, slice_dur INT',
- '
- SELECT slice_name, slice_dur
- FROM android_thread_slices_for_all_startups s
- WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
- ORDER BY slice_dur DESC
- LIMIT $top_n
- '
-);
+CREATE PERFETTO FUNCTION get_long_slices_for_launch(
+ startup_id INT, slice_name STRING, top_n INT)
+RETURNS TABLE(slice_name STRING, slice_dur INT) AS
+SELECT slice_name, slice_dur
+FROM android_thread_slices_for_all_startups s
+WHERE s.startup_id = $startup_id AND s.slice_name GLOB $slice_name
+ORDER BY slice_dur DESC
+LIMIT $top_n;
-- Define the view
DROP VIEW IF EXISTS startup_view;
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
index 9c891af..0814320 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_slices.sql
@@ -190,30 +190,30 @@
-- slice for each of the layers. GROUP BY to deduplicate these rows.
GROUP BY cuj_id, app_upid, app_vsync, sf_upid, sf_vsync;
-SELECT CREATE_VIEW_FUNCTION(
- 'FIND_ANDROID_JANK_CUJ_SF_MAIN_THREAD_SLICE(slice_name_glob STRING)',
- 'cuj_id INT, utid INT, vsync INT, id INT, name STRING, ts LONG, dur LONG, ts_end LONG',
- '
- WITH sf_vsync AS (
- SELECT DISTINCT cuj_id, sf_vsync AS vsync
- FROM android_jank_cuj_app_to_sf_match)
- SELECT
- cuj_id,
- utid,
- sf_vsync.vsync,
- slice.id,
- slice.name,
- slice.ts,
- slice.dur,
- slice.ts + slice.dur AS ts_end
- FROM slice
- JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
- JOIN sf_vsync
- ON vsync_from_name(slice.name) = sf_vsync.vsync
- WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
- ORDER BY cuj_id, vsync;
- '
-);
+CREATE PERFETTO FUNCTION find_android_jank_cuj_sf_main_thread_slice(
+ slice_name_glob STRING)
+RETURNS TABLE(
+ cuj_id INT, utid INT, vsync INT, id INT,
+ name STRING, ts LONG, dur LONG, ts_end LONG)
+AS
+WITH sf_vsync AS (
+ SELECT DISTINCT cuj_id, sf_vsync AS vsync
+ FROM android_jank_cuj_app_to_sf_match)
+SELECT
+ cuj_id,
+ utid,
+ sf_vsync.vsync,
+ slice.id,
+ slice.name,
+ slice.ts,
+ slice.dur,
+ slice.ts + slice.dur AS ts_end
+FROM slice
+JOIN android_jank_cuj_sf_main_thread main_thread USING (track_id)
+JOIN sf_vsync
+ ON vsync_from_name(slice.name) = sf_vsync.vsync
+WHERE slice.name GLOB $slice_name_glob AND slice.dur > 0
+ORDER BY cuj_id, vsync;
DROP TABLE IF EXISTS android_jank_cuj_sf_commit_slice;
CREATE PERFETTO TABLE android_jank_cuj_sf_commit_slice AS
diff --git a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
index b647721..d3fc193 100644
--- a/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
+++ b/src/trace_processor/metrics/sql/android/jank/relevant_threads.sql
@@ -25,22 +25,18 @@
-- Some CUJs use a dedicated thread for Choreographer callbacks
OR (p.main_thread_override = thread.name);
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_JANK_CUJ_APP_THREAD(thread_name STRING)',
- 'cuj_id INT, upid INT, utid INT, name STRING, track_id INT',
- '
- SELECT
- cuj_id,
- cuj.upid,
- utid,
- thread.name,
- thread_track.id AS track_id
- FROM thread
- JOIN android_jank_cuj cuj USING (upid)
- JOIN thread_track USING (utid)
- WHERE thread.name = $thread_name;
- '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_app_thread(thread_name STRING)
+RETURNS TABLE(cuj_id INT, upid INT, utid INT, name STRING, track_id INT) AS
+SELECT
+ cuj_id,
+ cuj.upid,
+ utid,
+ thread.name,
+ thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj cuj USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
DROP TABLE IF EXISTS android_jank_cuj_render_thread;
CREATE PERFETTO TABLE android_jank_cuj_render_thread AS
@@ -68,17 +64,13 @@
JOIN thread_track USING (utid)
WHERE thread.is_main_thread;
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_JANK_CUJ_SF_THREAD(thread_name STRING)',
- 'upid INT, utid INT, name STRING, track_id INT',
- '
- SELECT upid, utid, thread.name, thread_track.id AS track_id
- FROM thread
- JOIN android_jank_cuj_sf_process sf_process USING (upid)
- JOIN thread_track USING (utid)
- WHERE thread.name = $thread_name;
- '
-);
+CREATE PERFETTO FUNCTION android_jank_cuj_sf_thread(thread_name STRING)
+RETURNS TABLE(upid INT, utid INT, name STRING, track_id INT) AS
+SELECT upid, utid, thread.name, thread_track.id AS track_id
+FROM thread
+JOIN android_jank_cuj_sf_process sf_process USING (upid)
+JOIN thread_track USING (utid)
+WHERE thread.name = $thread_name;
DROP TABLE IF EXISTS android_jank_cuj_sf_gpu_completion_thread;
CREATE PERFETTO TABLE android_jank_cuj_sf_gpu_completion_thread AS
diff --git a/src/trace_processor/metrics/sql/android/p_state.sql b/src/trace_processor/metrics/sql/android/p_state.sql
index 79d2155..b334fcd 100644
--- a/src/trace_processor/metrics/sql/android/p_state.sql
+++ b/src/trace_processor/metrics/sql/android/p_state.sql
@@ -38,35 +38,32 @@
p_state_cpu_idle_counter PARTITIONED cpu
);
+CREATE PERFETTO FUNCTION p_state_over_interval(
+ start_ns LONG, end_ns LONG)
+RETURNS TABLE(cpu INT, freq_khz INT, idle_value INT, dur_ns INT)
+AS
+WITH sched_freq_idle_windowed AS (
+ SELECT
+ freq_khz,
+ idle_value,
+ cpu,
+ IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
+ FROM
+ p_state_sched_freq_idle
+ WHERE
+ ts + dur > $start_ns
+ AND ts < $end_ns
+)
SELECT
- CREATE_VIEW_FUNCTION(
- 'P_STATE_OVER_INTERVAL(start_ns LONG, end_ns LONG)',
- 'cpu INT, freq_khz INT, idle_value INT, dur_ns INT',
- '
- WITH sched_freq_idle_windowed AS (
- SELECT
- freq_khz,
- idle_value,
- cpu,
- IIF(ts + dur <= $end_ns, ts + dur, $end_ns) - IIF(ts >= $start_ns, ts, $start_ns) AS dur
- FROM
- p_state_sched_freq_idle
- WHERE
- ts + dur > $start_ns
- AND ts < $end_ns
- )
- SELECT
- cast(cpu AS int) AS cpu,
- cast(freq_khz AS int) AS freq_khz,
- cast(idle_value AS int) AS idle_value,
- cast(sum(dur) AS int) AS dur_ns
- FROM
- sched_freq_idle_windowed
- WHERE
- freq_khz > 0
- GROUP BY
- cpu,
- freq_khz,
- idle_value
- '
- );
+ cast(cpu AS int) AS cpu,
+ cast(freq_khz AS int) AS freq_khz,
+ cast(idle_value AS int) AS idle_value,
+ cast(sum(dur) AS int) AS dur_ns
+FROM
+ sched_freq_idle_windowed
+WHERE
+ freq_khz > 0
+GROUP BY
+ cpu,
+ freq_khz,
+ idle_value;
diff --git a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
index e003302..7a12590 100644
--- a/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
+++ b/src/trace_processor/metrics/sql/android/startup/slice_functions.sql
@@ -138,17 +138,14 @@
ELSE $loc
END || ": " || $status || "/" || $filter_str || "/" || $reason;
-SELECT CREATE_VIEW_FUNCTION(
- 'BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(startup_id INT, threshold DOUBLE)',
- 'name STRING',
- '
- SELECT reply.name AS name
- FROM ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP($startup_id, $threshold) request
- JOIN following_flow(request.id) arrow
- JOIN slice reply ON reply.id = arrow.slice_in
- WHERE reply.dur > $threshold AND request.is_main_thread
- '
-);
+CREATE PERFETTO FUNCTION binder_transaction_reply_slices_for_launch(
+ startup_id INT, threshold DOUBLE)
+RETURNS TABLE(name STRING) AS
+SELECT reply.name AS name
+FROM android_binder_transaction_slices_for_startup($startup_id, $threshold) request
+JOIN following_flow(request.id) arrow
+JOIN slice reply ON reply.id = arrow.slice_in
+WHERE reply.dur > $threshold AND request.is_main_thread;
-- Given a launch id, return if unlock is running by systemui during the launch.
CREATE PERFETTO FUNCTION is_unlock_running_during_launch(startup_id LONG)
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
index e80913e..e483965 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_long_tasks.sql
@@ -23,30 +23,38 @@
-- names. For example, LongTaskTracker slices may have associated IPC
-- metadata, or InterestingTask slices for input may have associated IPC to
-- determine whether the task is fling/etc.
-SELECT CREATE_VIEW_FUNCTION(
- 'SELECT_LONG_TASK_SLICES(name STRING)',
- 'interface_name STRING, ipc_hash INT, message_type STRING, id INT, task_name STRING',
- '
- WITH slices_with_mojo_data AS (
- SELECT
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
- CASE
- WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
- ELSE "message"
- END AS message_type,
- id
- FROM slice
- WHERE
- category GLOB "*scheduler.long_tasks*"
- AND name = $name
- )
- SELECT
- *,
- printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
- FROM slices_with_mojo_data;
- '
-);
+CREATE PERFETTO FUNCTION select_long_task_slices(name STRING)
+RETURNS TABLE(
+ interface_name STRING,
+ ipc_hash INT,
+ message_type STRING,
+ id INT,
+ task_name STRING)
+AS
+WITH slices_with_mojo_data AS (
+ SELECT
+ EXTRACT_ARG(
+ arg_set_id,
+ "chrome_mojo_event_info.mojo_interface_tag"
+ ) AS interface_name,
+ EXTRACT_ARG(
+ arg_set_id,
+ "chrome_mojo_event_info.ipc_hash"
+ ) AS ipc_hash,
+ CASE
+ WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+ ELSE "message"
+ END AS message_type,
+ id
+ FROM slice
+ WHERE
+ category GLOB "*scheduler.long_tasks*"
+ AND name = $name
+)
+SELECT
+ *,
+ printf("%s %s(hash=%s)", interface_name, message_type, ipc_hash) as task_name
+FROM slices_with_mojo_data;
CREATE PERFETTO FUNCTION is_long_choreographer_task(dur LONG)
RETURNS BOOL AS
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
index ba96dc3..3cf320c 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_tasks_delaying_input_processing_base.sql
@@ -23,23 +23,20 @@
-- browser interval. This may differ based on whether the scenario is for
-- topLevel events or LongTask events.
-SELECT CREATE_VIEW_FUNCTION(
- '{{function_prefix}}SELECT_SLOW_BROWSER_TASKS()',
- 'full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT',
- 'SELECT
- task_table.full_name AS full_name,
- task_table.dur AS dur,
- task_table.ts AS ts,
- task_table.id AS id,
- task_table.upid AS upid,
- thread_dur
- FROM
- {{task_table_name}} task_table
- WHERE
- task_table.dur >= {{duration_causing_jank_ms}} * 1e6
- AND task_table.thread_name = "CrBrowserMain"
- '
-);
+CREATE PERFETTO FUNCTION {{function_prefix}}SELECT_SLOW_BROWSER_TASKS()
+RETURNS TABLE(full_name STRING, dur INT, ts INT, id INT, upid INT, thread_dur INT) AS
+SELECT
+ task_table.full_name AS full_name,
+ task_table.dur AS dur,
+ task_table.ts AS ts,
+ task_table.id AS id,
+ task_table.upid AS upid,
+ thread_dur
+FROM
+ {{task_table_name}} task_table
+WHERE
+ task_table.dur >= {{duration_causing_jank_ms}} * 1e6
+ AND task_table.thread_name = "CrBrowserMain";
-- Get the tasks that was running for more than 8ms within windows
-- that we could have started processing input but did not on the
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
index 521f2fc..2cfdce0 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/startup/startups.sql
@@ -211,15 +211,18 @@
-- @column slice_dur Duration of the slice.
-- @column thread_name Name of the thread with the slice.
-- @column arg_set_id Arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(startup_id INT, slice_name STRING)',
- 'slice_name STRING, slice_ts INT, slice_dur INT, thread_name STRING, arg_set_id INT',
- '
- SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
- FROM android_thread_slices_for_all_startups
- WHERE startup_id = $startup_id AND slice_name GLOB $slice_name
- '
-);
+CREATE PERFETTO FUNCTION android_slices_for_startup_and_slice_name(
+ startup_id INT, slice_name STRING)
+RETURNS TABLE(
+ slice_name STRING,
+ slice_ts INT,
+ slice_dur INT,
+ thread_name STRING,
+ arg_set_id INT
+) AS
+SELECT slice_name, slice_ts, slice_dur, thread_name, arg_set_id
+FROM android_thread_slices_for_all_startups
+WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
-- Returns binder transaction slices for a given startup id with duration over threshold.
--
@@ -231,18 +234,30 @@
-- @column process Name of the process with slice.
-- @column arg_set_id Arg set id.
-- @column is_main_thread Whether is main thread.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_BINDER_TRANSACTION_SLICES_FOR_STARTUP(startup_id INT, threshold DOUBLE)',
- 'id INT, slice_dur INT, thread_name STRING, process STRING, arg_set_id INT, is_main_thread BOOL',
- '
- SELECT slice_id as id, slice_dur, thread_name, process.name as process, s.arg_set_id, is_main_thread
- FROM android_thread_slices_for_all_startups s
- JOIN process ON (
- EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
- )
- WHERE startup_id = $startup_id AND slice_name GLOB "binder transaction" AND slice_dur > $threshold
- '
-);
+CREATE PERFETTO FUNCTION android_binder_transaction_slices_for_startup(
+ startup_id INT, threshold DOUBLE)
+RETURNS TABLE(
+ id INT,
+ slice_dur INT,
+ thread_name STRING,
+ process STRING,
+ arg_set_id INT,
+ is_main_thread BOOL
+) AS
+SELECT
+ slice_id as id,
+ slice_dur,
+ thread_name,
+ process.name as process,
+ s.arg_set_id,
+ is_main_thread
+FROM android_thread_slices_for_all_startups s
+JOIN process ON (
+ EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid
+)
+WHERE startup_id = $startup_id
+ AND slice_name GLOB "binder transaction"
+ AND slice_dur > $threshold;
-- Returns duration of startup for slice name.
--
@@ -251,11 +266,13 @@
-- @arg startup_id LONG Startup id.
-- @arg slice_name STRING Slice name.
-- @ret INT Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_for_startup_and_slice(
+ startup_id LONG, slice_name STRING)
RETURNS INT AS
SELECT SUM(slice_dur)
FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name;
+WHERE startup_id = $startup_id
+ AND slice_name GLOB $slice_name;
-- Returns duration of startup for slice name on main thread.
--
@@ -264,8 +281,11 @@
-- @arg startup_id LONG Startup id.
-- @arg slice_name STRING Slice name.
-- @ret INT Sum of duration.
-CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(startup_id LONG, slice_name STRING)
+CREATE PERFETTO FUNCTION android_sum_dur_on_main_thread_for_startup_and_slice(
+ startup_id LONG, slice_name STRING)
RETURNS INT AS
SELECT SUM(slice_dur)
FROM android_thread_slices_for_all_startups
-WHERE startup_id = $startup_id AND slice_name GLOB $slice_name AND is_main_thread;
+WHERE startup_id = $startup_id
+ AND slice_name GLOB $slice_name
+ AND is_main_thread;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
index 3d6fa46..592b476 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/thread.sql
@@ -28,34 +28,36 @@
-- @column pid Process pid creating threads.
-- @column thread_name_prefix String prefix of thread names created.
-- @column max_count_per_sec Max number of threads created within a time window.
-SELECT CREATE_VIEW_FUNCTION(
- 'ANDROID_THREAD_CREATION_SPAM(min_thread_dur FLOAT, sliding_window_dur FLOAT)',
- 'process_name STRING, pid INT, thread_name_prefix STRING, max_count_per_sec INT',
- '
- WITH
- x AS (
- SELECT
- pid,
- upid,
- INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
- process.name AS process_name,
- COUNT(thread.start_ts)
- OVER (
- PARTITION BY upid, thread.name
- ORDER BY thread.start_ts
- RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
- ) AS count
- FROM thread
- JOIN process
- USING (upid)
- WHERE
- ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
- OR $min_thread_dur IS NULL
- )
- SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
- FROM x
- GROUP BY upid, thread_name_prefix
- HAVING max_count_per_sec > 0
- ORDER BY count DESC;
- '
-);
+CREATE PERFETTO FUNCTION android_thread_creation_spam(
+ min_thread_dur FLOAT, sliding_window_dur FLOAT)
+RETURNS TABLE(
+ process_name STRING,
+ pid INT,
+ thread_name_prefix STRING,
+ max_count_per_sec INT
+) AS
+WITH
+x AS (
+ SELECT
+ pid,
+ upid,
+ INTERNAL_THREAD_PREFIX(thread.name) AS thread_name_prefix,
+ process.name AS process_name,
+ COUNT(thread.start_ts)
+ OVER (
+ PARTITION BY upid, thread.name
+ ORDER BY thread.start_ts
+ RANGE BETWEEN CURRENT ROW AND CAST($sliding_window_dur AS INT64) FOLLOWING
+ ) AS count
+ FROM thread
+ JOIN process
+ USING (upid)
+ WHERE
+ ($min_thread_dur AND (thread.end_ts - thread.start_ts) <= $min_thread_dur)
+ OR $min_thread_dur IS NULL
+)
+SELECT process_name, pid, thread_name_prefix, MAX(count) AS max_count_per_sec
+FROM x
+GROUP BY upid, thread_name_prefix
+HAVING max_count_per_sec > 0
+ORDER BY count DESC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
index 167bca2..44e6e1e 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/scroll_jank/utils.sql
@@ -95,20 +95,22 @@
-- @column ipc_hash Hash of the IPC call.
-- @column message_type Message type (e.g. reply).
-- @column id The slice ID.
-SELECT CREATE_VIEW_FUNCTION(
- 'CHROME_SELECT_LONG_TASK_SLICES(name STRING)',
- 'interface_name STRING, ipc_hash INT, message_type STRING, id INT',
- 'SELECT
- EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
- EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
- CASE
- WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
- ELSE "message"
- END AS message_type,
- s.id
- FROM slice s
- WHERE
- category GLOB "*scheduler.long_tasks*"
- AND name = $name
- '
-);
+CREATE PERFETTO FUNCTION chrome_select_long_task_slices(name STRING)
+RETURNS TABLE(
+ interface_name STRING,
+ ipc_hash INT,
+ message_type STRING,
+ id INT
+) AS
+SELECT
+ EXTRACT_ARG(s.arg_set_id, "chrome_mojo_event_info.mojo_interface_tag") AS interface_name,
+ EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.ipc_hash") AS ipc_hash,
+ CASE
+ WHEN EXTRACT_ARG(arg_set_id, "chrome_mojo_event_info.is_reply") THEN "reply"
+ ELSE "message"
+ END AS message_type,
+ s.id
+FROM slice s
+WHERE
+ category GLOB "*scheduler.long_tasks*"
+ AND name = $name;
diff --git a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
index cd45beb..6890ce7 100644
--- a/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/chrome/tasks.sql
@@ -43,7 +43,8 @@
LIMIT 1;
-- Human-readable aliases for a few key navigation tasks.
-CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(task_name STRING)
+CREATE PERFETTO FUNCTION internal_human_readable_navigation_task_name(
+ task_name STRING)
RETURNS STRING AS
SELECT
CASE
@@ -310,22 +311,20 @@
-- @column kind The type of Java slice.
-- @column ts The timestamp of the slice.
-- @column name The name of the slice.
-SELECT CREATE_VIEW_FUNCTION(
- 'INTERNAL_SELECT_BEGIN_MAIN_FRAME_JAVA_SLICES(name STRING)',
- 'id INT, kind STRING, ts LONG, dur LONG, name STRING',
- 'SELECT
- id,
- "SingleThreadProxy::BeginMainFrame" AS kind,
- ts,
- dur,
- name
- FROM slice
- WHERE
- (name = $name
- AND internal_get_posted_from(arg_set_id) =
- "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame")
- '
-);
+CREATE PERFETTO FUNCTION internal_select_begin_main_frame_java_slices(
+ name STRING)
+RETURNS TABLE(id INT, kind STRING, ts LONG, dur LONG, name STRING) AS
+SELECT
+ id,
+ "SingleThreadProxy::BeginMainFrame" AS kind,
+ ts,
+ dur,
+ name
+FROM slice
+WHERE
+ (name = $name
+ AND internal_get_posted_from(arg_set_id) =
+ "cc/trees/single_thread_proxy.cc:ScheduledActionSendBeginMainFrame");
-- A list of Chrome tasks which were performing operations with Java views,
-- together with the names of the these views.
@@ -436,17 +435,15 @@
ORDER by depth, ts
LIMIT 1;
-SELECT CREATE_VIEW_FUNCTION('INTERNAL_DESCENDANT_MOJO_SLICE(slice_id INT)',
- 'task_name STRING',
- '
- SELECT
- printf("%s %s (hash=%d)",
- mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
- FROM slice task
- JOIN internal_chrome_mojo_slices mojo
- ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
- WHERE task.id = $slice_id
- ');
+CREATE PERFETTO FUNCTION internal_descendant_mojo_slice(slice_id INT)
+RETURNS TABLE(task_name STRING) AS
+SELECT
+ printf("%s %s (hash=%d)",
+ mojo.interface_name, mojo.message_type, mojo.ipc_hash) AS task_name
+FROM slice task
+JOIN internal_chrome_mojo_slices mojo
+ ON mojo.id = internal_get_descendant_mojo_slice_candidate($slice_id)
+WHERE task.id = $slice_id;
-- A list of "Chrome tasks": top-level execution units (e.g. scheduler tasks /
-- IPCs / system callbacks) run by Chrome. For a given thread, the tasks
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/args.sql b/src/trace_processor/perfetto_sql/stdlib/common/args.sql
index 7361e93..150fae4 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/args.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/args.sql
@@ -12,20 +12,6 @@
-- 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.
---
--- Copyright 2023 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
---
--- https://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.
-- Returns the formatted value of a given argument.
-- Similar to EXTRACT_ARG, but instead of returning the raw value, it returns
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
index 91e023d..a7f3157 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/counters.sql
@@ -34,9 +34,8 @@
-- @column track_name Name of the counter track.
-- @column track_arg_set_id Counter track set id.
-- @column arg_set_id Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_WITH_DUR_FOR_TRACK(counter_track_id INT)',
- '
+CREATE PERFETTO FUNCTION counter_with_dur_for_track(counter_track_id INT)
+RETURNS TABLE(
ts LONG,
dur LONG,
value DOUBLE,
@@ -44,21 +43,18 @@
track_name STRING,
track_arg_set_id INT,
arg_set_id INT
- ',
- '
- SELECT
- ts,
- LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
- value,
- track.id AS track_id,
- track.name AS track_name,
- track.source_arg_set_id AS track_arg_set_id,
- counter.arg_set_id AS arg_set_id
- FROM counter
- JOIN counter_track track ON track.id = counter.track_id
- WHERE track.id = $counter_track_id
- '
-);
+) AS
+SELECT
+ ts,
+ LEAD(ts, 1, trace_end()) OVER(ORDER BY ts) - ts AS dur,
+ value,
+ track.id AS track_id,
+ track.name AS track_name,
+ track.source_arg_set_id AS track_arg_set_id,
+ counter.arg_set_id AS arg_set_id
+FROM counter
+JOIN counter_track track ON track.id = counter.track_id
+WHERE track.id = $counter_track_id;
-- COUNTER_WITH_DUR_FOR_TRACK but in a specified time.
-- Does calculation over the table ends - creates an artificial counter value at
@@ -75,33 +71,30 @@
-- @column track_name Name of the counter track.
-- @column track_arg_set_id Counter track set id.
-- @column arg_set_id Counter arg set id.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
- '
- ts LONG,
- dur LONG,
- value DOUBLE,
- track_id INT,
- track_name STRING,
- track_arg_set_id INT,
- arg_set_id INT
- ',
- '
- SELECT
- IIF(ts < $start_ts, $start_ts, ts) AS ts,
- IIF(
- ts < $start_ts,
- dur - ($start_ts - ts),
- IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
- value,
- track_id,
- track_name,
- track_arg_set_id,
- arg_set_id
- FROM COUNTER_WITH_DUR_FOR_TRACK($counter_track_id)
- WHERE TRUE
- AND ts + dur >= $start_ts
- AND ts < $end_ts
- ORDER BY ts ASC;
-'
-);
\ No newline at end of file
+CREATE PERFETTO FUNCTION COUNTER_FOR_TIME_RANGE(
+ counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(
+ ts LONG,
+ dur LONG,
+ value DOUBLE,
+ track_id INT,
+ track_name STRING,
+ track_arg_set_id INT,
+ arg_set_id INT
+) AS
+SELECT
+ IIF(ts < $start_ts, $start_ts, ts) AS ts,
+ IIF(
+ ts < $start_ts,
+ dur - ($start_ts - ts),
+ IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
+ value,
+ track_id,
+ track_name,
+ track_arg_set_id,
+ arg_set_id
+FROM counter_with_dur_for_track($counter_track_id)
+WHERE TRUE
+ AND ts + dur >= $start_ts
+ AND ts < $end_ts
+ORDER BY ts ASC;
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
index bbba1eb..8b3da9d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/percentiles.sql
@@ -16,15 +16,13 @@
INCLUDE PERFETTO MODULE common.counters;
INCLUDE PERFETTO MODULE common.timestamps;
-SELECT CREATE_VIEW_FUNCTION(
- 'INTERNAL_NUMBER_GENERATOR(to INT)',
- 'num INT',
- 'WITH NUMS AS
- (SELECT 1 num UNION SELECT num + 1
- from NUMS
- WHERE num < $to)
- SELECT num FROM NUMS;'
-);
+CREATE PERFETTO FUNCTION internal_number_generator(to INT)
+RETURNS TABLE(num INT) AS
+WITH nums AS
+ (SELECT 1 num UNION SELECT num + 1
+ from NUMS
+ WHERE num < $to)
+SELECT num FROM nums;
--
-- Get durations for percentile
@@ -46,44 +44,43 @@
-- @arg end_ts LONG Timestamp of end of time range.
-- @column percentile All of the numbers from 1 to 100.
-- @column value Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_PERCENTILES_FOR_TIME_RANGE(counter_track_id INT, start_ts LONG, end_ts LONG)',
- 'percentile INT, value DOUBLE',
- 'WITH percentiles_for_value AS (
- SELECT
- value,
- (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
- ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
- AS percentile_for_value
- FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
- ORDER BY value ASC
- ),
- with_gaps AS (
- SELECT
- CAST(percentile_for_value AS INT) AS percentile,
- MIN(value) AS value
- FROM percentiles_for_value
- GROUP BY percentile
- ORDER BY percentile ASC)
+CREATE PERFETTO FUNCTION counter_percentiles_for_time_range(
+ counter_track_id INT, start_ts LONG, end_ts LONG)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+WITH percentiles_for_value AS (
SELECT
- num AS percentile,
- IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
- FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
- LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
- ORDER BY percentile DESC
- '
-);
+ value,
+ (CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
+ ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
+ AS percentile_for_value
+ FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+ ORDER BY value ASC
+),
+with_gaps AS (
+ SELECT
+ CAST(percentile_for_value AS INT) AS percentile,
+ MIN(value) AS value
+ FROM percentiles_for_value
+ GROUP BY percentile
+ ORDER BY percentile ASC)
+SELECT
+ num AS percentile,
+ IFNULL(value, MIN(value) OVER (ORDER BY percentile DESC)) AS value
+FROM INTERNAL_NUMBER_GENERATOR(100) AS nums
+LEFT JOIN with_gaps ON with_gaps.percentile = nums.num
+ORDER BY percentile DESC;
-- All percentiles (range 1-100) for counter track ID.
--
-- @arg counter_track_id INT Id of the counter track.
-- @column percentile All of the numbers from 1 to 100.
-- @column value Value for the percentile.
-SELECT CREATE_VIEW_FUNCTION(
- 'COUNTER_PERCENTILES_FOR_TRACK(counter_track_id INT)',
- 'percentile INT, value DOUBLE',
- 'SELECT * FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, trace_start(), trace_end());'
-);
+CREATE PERFETTO FUNCTION counter_percentiles_for_track(
+ counter_track_id INT)
+RETURNS TABLE(percentile INT, value DOUBLE) AS
+SELECT *
+FROM counter_percentiles_for_time_range(
+ $counter_track_id, trace_start(), trace_end());
-- Value for specific percentile (range 1-100) for counter track ID in time range.
--
@@ -98,7 +95,7 @@
end_ts LONG)
RETURNS DOUBLE AS
SELECT value
-FROM COUNTER_PERCENTILES_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+FROM counter_percentiles_for_time_range($counter_track_id, $start_ts, $end_ts)
WHERE percentile = $percentile;
-- Value for specific percentile (range 1-100) for counter track ID.
diff --git a/src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql b/src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql
index 2aa0d47..df95849 100644
--- a/src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql
@@ -66,3 +66,56 @@
WHEN ($ts1 > $ts2) AND ($ts1 + $dur1 > $ts2 + $dur2) THEN $ts2 + $dur2 - $ts1
ELSE $dur2
END;
+
+--
+-- Helpers for defining time durations.
+--
+
+-- Converts a duration in seconds to nanoseconds, which is the default representation
+-- of time durations in trace processor. Provided for consisensy with other functions.
+-- @arg nanos INT Time duration in seconds.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION ns(nanos INT) RETURNS INT AS
+SELECT $nanos;
+
+-- Converts a duration in microseconds to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg micros INT Time duration in microseconds.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION us(micros INT) RETURNS INT AS
+SELECT $micros * 1000;
+
+-- Converts a duration in millseconds to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg millis INT Time duration in milliseconds.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION ms(millis INT) RETURNS INT AS
+SELECT $millis * 1000 * 1000;
+
+-- Converts a duration in seconds to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg seconds INT Time duration in seconds.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION seconds(seconds INT) RETURNS INT AS
+SELECT $seconds * 1000 * 1000 * 1000;
+
+-- Converts a duration in minutes to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg minutes INT Time duration in minutes.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION minutes(minutes INT) RETURNS INT AS
+SELECT $minutes * 60 * 1000 * 1000 * 1000;
+
+-- Converts a duration in hours to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg hours INT Time duration in hours.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION hours(hours INT) RETURNS INT AS
+SELECT $hours * 60 * 60 * 1000 * 1000 * 1000;
+
+-- Converts a duration in days to nanoseconds, which is the default
+-- representation of time durations in trace processor.
+-- @arg days INT Time duration in days.
+-- @ret INT Time duration in nanoseconds.
+CREATE PERFETTO FUNCTION days(days INT) RETURNS INT AS
+SELECT $days * 24 * 60 * 60 * 1000 * 1000 * 1000;
diff --git a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
index 5b7bf03..f839818 100644
--- a/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/experimental/thread_executing_span.sql
@@ -347,9 +347,8 @@
-- @column is_leaf Whether this span is the leaf in the slice tree.
-- @column depth Tree depth from |root_id|
-- @column root_id Thread state id used to start the recursion. Helpful for SQL JOINs
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_DESCENDANTS(root_id INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_descendants(root_id INT)
+RETURNS TABLE(
parent_id LONG,
id LONG,
ts LONG,
@@ -373,8 +372,7 @@
is_leaf INT,
depth INT,
root_id INT
-',
-'
+) AS
WITH chain AS (
SELECT
*,
@@ -390,8 +388,7 @@
FROM experimental_thread_executing_span_graph graph
JOIN chain ON chain.id = graph.parent_id
)
-SELECT * FROM chain
-');
+SELECT * FROM chain;
-- All thread_executing_spans that are ancestors of |leaf_id|.
--
@@ -426,9 +423,8 @@
-- @column leaf_blocked_dur Thread state duration blocked of the |leaf_id|.
-- @column leaf_blocked_state Thread state of the |leaf_id|.
-- @column leaf_blocked_function Thread state blocked_function of the |leaf_id|.
-SELECT CREATE_VIEW_FUNCTION(
-'EXPERIMENTAL_THREAD_EXECUTING_SPAN_ANCESTORS(leaf_id INT, leaf_utid INT)',
-'
+CREATE PERFETTO FUNCTION experimental_thread_executing_span_ancestors(leaf_id INT, leaf_utid INT)
+RETURNS TABLE(
parent_id LONG,
id LONG,
ts LONG,
@@ -457,8 +453,7 @@
leaf_blocked_dur LONG,
leaf_blocked_state STRING,
leaf_blocked_function STRING
-',
-'
+) AS
WITH
chain AS (
SELECT
@@ -486,8 +481,7 @@
FROM experimental_thread_executing_span_graph graph
JOIN chain ON chain.parent_id = graph.id AND chain.ts >= (leaf_ts - leaf_blocked_dur)
)
-SELECT * FROM chain
-');
+SELECT * FROM chain;
-- Gets the thread_executing_span id a thread_state belongs to. Returns NULL if thread state is
-- sleeping and not blocked on an interrupt.
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index 2f7b62f..b960520 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -89,6 +89,7 @@
from diff_tests.tables.tests import Tables
from diff_tests.tables.tests_counters import TablesCounters
from diff_tests.tables.tests_sched import TablesSched
+from diff_tests.time.tests import Time
from diff_tests.track_event.tests import TrackEvent
from diff_tests.translation.tests import Translation
from diff_tests.ufs.tests import Ufs
@@ -178,6 +179,7 @@
*Tables(index_path, 'tables', 'Tables').fetch(),
*TablesCounters(index_path, 'tables', 'TablesCounters').fetch(),
*TablesSched(index_path, 'tables', 'TablesSched').fetch(),
+ *Time(index_path, 'time', 'Time').fetch(),
*TrackEvent(index_path, 'track_event', 'TrackEvent').fetch(),
*Translation(index_path, 'translation', 'Translation').fetch(),
*WebView(index_path, 'webview', 'WebView').fetch(),
diff --git a/test/trace_processor/diff_tests/time/tests.py b/test/trace_processor/diff_tests/time/tests.py
new file mode 100644
index 0000000..5731169
--- /dev/null
+++ b/test/trace_processor/diff_tests/time/tests.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# Copyright (C) 2023 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 a
+#
+# 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.
+
+from python.generators.diff_tests.testing import Path, DataPath, Metric
+from python.generators.diff_tests.testing import Csv, Json, TextProto, BinaryProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+from google.protobuf import text_format
+
+
+class Time(TestSuite):
+
+ def test_ns(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT ns(4) as result;
+ """,
+ out=Csv("""
+ "result"
+ 4
+ """))
+
+ def test_us(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT us(4) as result;
+ """,
+ out=Csv("""
+ "result"
+ 4000
+ """))
+
+ def test_ms(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT ms(4) as result;
+ """,
+ out=Csv("""
+ "result"
+ 4000000
+ """))
+
+ def test_seconds(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT seconds(4) as result;
+ """,
+ out=Csv("""
+ "result"
+ 4000000000
+ """))
+
+ def test_minutes(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT minutes(1) as result;
+ """,
+ out=Csv("""
+ "result"
+ 60000000000
+ """))
+
+ def test_hours(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT hours(1) as result;
+ """,
+ out=Csv("""
+ "result"
+ 3600000000000
+ """))
+
+ def test_days(self):
+ return DiffTestBlueprint(
+ trace=TextProto(""),
+ query="""
+ SELECT IMPORT('common.timestamps');
+ SELECT days(1) as result;
+ """,
+ out=Csv("""
+ "result"
+ 86400000000000
+ """))
diff --git a/ui/src/base/dom_utils.ts b/ui/src/base/dom_utils.ts
index e2c8e73..d7c7582 100644
--- a/ui/src/base/dom_utils.ts
+++ b/ui/src/base/dom_utils.ts
@@ -62,3 +62,23 @@
return true;
}
+
+// Returns the mouse pointer's position relative to |e.currentTarget| for a
+// given |MouseEvent|.
+// Similar to |offsetX|, |offsetY| but for |currentTarget| rather than |target|.
+// If the event has no currentTarget or it is not an element, offsetX & offsetY
+// are returned instead.
+export function currentTargetOffset(e: MouseEvent): {x: number, y: number} {
+ if (e.currentTarget === e.target) {
+ return {x: e.offsetX, y: e.offsetY};
+ }
+
+ if (e.currentTarget && e.currentTarget instanceof Element) {
+ const rect = e.currentTarget.getBoundingClientRect();
+ const offsetX = e.clientX - rect.left;
+ const offsetY = e.clientY - rect.top;
+ return {x: offsetX, y: offsetY};
+ }
+
+ return {x: e.offsetX, y: e.offsetY};
+}
diff --git a/ui/src/frontend/events.ts b/ui/src/frontend/events.ts
deleted file mode 100644
index 88e044b..0000000
--- a/ui/src/frontend/events.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2020 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use size 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.
-
-// layerX and layerY aren't standardized but there is no drop-in replacement
-// (offsetX/offsetY have slightly different semantics) and they are still
-// present in the browsers we care about, so for now we create an extended
-// version of MouseEvent we can use instead.
-// See also:
-// https://github.com/microsoft/TypeScript/issues/35634#issuecomment-564765179
-export interface PerfettoMouseEvent extends MouseEvent {
- layerX: number;
- layerY: number;
-}
diff --git a/ui/src/frontend/notes_panel.ts b/ui/src/frontend/notes_panel.ts
index ea32ac1..1904f32 100644
--- a/ui/src/frontend/notes_panel.ts
+++ b/ui/src/frontend/notes_panel.ts
@@ -14,6 +14,7 @@
import m from 'mithril';
+import {currentTargetOffset} from '../base/dom_utils';
import {Icons} from '../base/semantic_icons';
import {Time} from '../base/time';
import {Actions} from '../common/actions';
@@ -28,7 +29,6 @@
NewBottomTabArgs,
} from './bottom_tab';
import {TRACK_SHELL_WIDTH} from './css_constants';
-import {PerfettoMouseEvent} from './events';
import {globals} from './globals';
import {
getMaxMajorTicks,
@@ -60,21 +60,6 @@
export class NotesPanel extends Panel {
hoveredX: null|number = null;
- oncreate({dom}: m.CVnodeDOM) {
- dom.addEventListener('mousemove', (e: Event) => {
- this.hoveredX = (e as PerfettoMouseEvent).layerX - TRACK_SHELL_WIDTH;
- raf.scheduleRedraw();
- }, {passive: true});
- dom.addEventListener('mouseenter', (e: Event) => {
- this.hoveredX = (e as PerfettoMouseEvent).layerX - TRACK_SHELL_WIDTH;
- raf.scheduleRedraw();
- });
- dom.addEventListener('mouseout', () => {
- this.hoveredX = null;
- globals.dispatch(Actions.setHoveredNoteTimestamp({ts: Time.INVALID}));
- }, {passive: true});
- }
-
view() {
const allCollapsed = Object.values(globals.state.trackGroups)
.every((group) => group.collapsed);
@@ -82,10 +67,24 @@
return m(
'.notes-panel',
{
- onclick: (e: PerfettoMouseEvent) => {
- this.onClick(e.layerX - TRACK_SHELL_WIDTH, e.layerY);
+ onclick: (e: MouseEvent) => {
+ const {x, y} = currentTargetOffset(e);
+ this.onClick(x - TRACK_SHELL_WIDTH, y);
e.stopPropagation();
},
+ onmousemove: (e: MouseEvent) => {
+ this.hoveredX = currentTargetOffset(e).x - TRACK_SHELL_WIDTH;
+ raf.scheduleRedraw();
+ },
+ mouseenter: (e: MouseEvent) => {
+ this.hoveredX = currentTargetOffset(e).x - TRACK_SHELL_WIDTH;
+ raf.scheduleRedraw();
+ },
+ onmouseout: () => {
+ this.hoveredX = null;
+ globals.dispatch(
+ Actions.setHoveredNoteTimestamp({ts: Time.INVALID}));
+ },
},
isTraceLoaded() ?
[
diff --git a/ui/src/frontend/pan_and_zoom_handler.ts b/ui/src/frontend/pan_and_zoom_handler.ts
index a70baa9..5d2c37a 100644
--- a/ui/src/frontend/pan_and_zoom_handler.ts
+++ b/ui/src/frontend/pan_and_zoom_handler.ts
@@ -13,12 +13,11 @@
// limitations under the License.
import {Disposable, Trash} from '../base/disposable';
-import {elementIsEditable} from '../base/dom_utils';
+import {currentTargetOffset, elementIsEditable} from '../base/dom_utils';
import {raf} from '../core/raf_scheduler';
import {Animation} from './animation';
import {DragGestureHandler} from './drag_gesture_handler';
-import {globals} from './globals';
import {handleKey} from './keyboard_event_handler';
// When first starting to pan or zoom, move at least this many units.
@@ -110,7 +109,6 @@
private zoomAnimation = new Animation(this.onZoomAnimationStep.bind(this));
private element: HTMLElement;
- private contentOffsetX: number;
private onPanned: (movedPx: number) => void;
private onZoomed: (zoomPositionPx: number, zoomRatio: number) => void;
private editSelection: (currentPx: number) => boolean;
@@ -122,7 +120,6 @@
constructor({
element,
- contentOffsetX,
onPanned,
onZoomed,
editSelection,
@@ -130,7 +127,6 @@
endSelection,
}: {
element: HTMLElement,
- contentOffsetX: number,
onPanned: (movedPx: number) => void,
onZoomed: (zoomPositionPx: number, zoomRatio: number) => void,
editSelection: (currentPx: number) => boolean,
@@ -140,7 +136,6 @@
endSelection: (edit: boolean) => void,
}) {
this.element = element;
- this.contentOffsetX = contentOffsetX;
this.onPanned = onPanned;
this.onZoomed = onZoomed;
this.editSelection = editSelection;
@@ -236,11 +231,8 @@
}
private onMouseMove(e: MouseEvent) {
- const pageOffset = globals.state.sidebarVisible && !globals.hideSidebar ?
- this.contentOffsetX :
- 0;
- // We can't use layerX here because there are many layers in this element.
- this.mousePositionX = e.clientX - pageOffset;
+ this.mousePositionX = currentTargetOffset(e).x;
+
// Only change the cursor when hovering, the DragGestureHandler handles
// changing the cursor during drag events. This avoids the problem of
// the cursor flickering between styles if you drag fast and get too
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index b9ff4a1..6fc7615 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -867,8 +867,14 @@
class: globals.state.sidebarVisible ? 'show-sidebar' : 'hide-sidebar',
// 150 here matches --sidebar-timing in the css.
// TODO(hjd): Should link to the CSS variable.
- ontransitionstart: () => this._redrawWhileAnimating.start(150),
- ontransitionend: () => this._redrawWhileAnimating.stop(),
+ ontransitionstart: (e: TransitionEvent) => {
+ if (e.target !== e.currentTarget) return;
+ this._redrawWhileAnimating.start(150);
+ },
+ ontransitionend: (e: TransitionEvent) => {
+ if (e.target !== e.currentTarget) return;
+ this._redrawWhileAnimating.stop();
+ },
},
shouldShowHiringBanner() ? m(HiringBanner) : null,
m(
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index 4d59dfa..1f333f6 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -15,6 +15,7 @@
import {hex} from 'color-convert';
import m from 'mithril';
+import {currentTargetOffset} from '../base/dom_utils';
import {Icons} from '../base/semantic_icons';
import {duration, Span, time} from '../base/time';
import {Actions} from '../common/actions';
@@ -25,7 +26,6 @@
import {TrackLike} from '../public';
import {SELECTION_FILL_COLOR, TRACK_SHELL_WIDTH} from './css_constants';
-import {PerfettoMouseEvent} from './events';
import {globals} from './globals';
import {drawGridLines} from './gridline_helper';
import {Panel, PanelSize} from './panel';
@@ -153,7 +153,7 @@
globals.state.currentSelection !== null &&
globals.state.currentSelection.kind === 'AREA' ?
m(TrackButton, {
- action: (e: PerfettoMouseEvent) => {
+ action: (e: MouseEvent) => {
globals.dispatch(Actions.toggleTrackSelection(
{id: attrs.trackState.id, isTrackGroup: false}));
e.stopPropagation();
@@ -231,32 +231,33 @@
return m(
'.track-content',
{
- onmousemove: (e: PerfettoMouseEvent) => {
- attrs.track.onMouseMove(
- {x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY});
+ onmousemove: (e: MouseEvent) => {
+ attrs.track.onMouseMove(currentTargetOffset(e));
raf.scheduleRedraw();
},
onmouseout: () => {
attrs.track.onMouseOut();
raf.scheduleRedraw();
},
- onmousedown: (e: PerfettoMouseEvent) => {
- this.mouseDownX = e.layerX;
- this.mouseDownY = e.layerY;
+ onmousedown: (e: MouseEvent) => {
+ const {x, y} = currentTargetOffset(e);
+ this.mouseDownX = x;
+ this.mouseDownY = y;
},
- onmouseup: (e: PerfettoMouseEvent) => {
+ onmouseup: (e: MouseEvent) => {
if (this.mouseDownX === undefined ||
this.mouseDownY === undefined) {
return;
}
- if (Math.abs(e.layerX - this.mouseDownX) > 1 ||
- Math.abs(e.layerY - this.mouseDownY) > 1) {
+ const {x, y} = currentTargetOffset(e);
+ if (Math.abs(x - this.mouseDownX) > 1 ||
+ Math.abs(y - this.mouseDownY) > 1) {
this.selectionOccurred = true;
}
this.mouseDownX = undefined;
this.mouseDownY = undefined;
},
- onclick: (e: PerfettoMouseEvent) => {
+ onclick: (e: MouseEvent) => {
// This click event occurs after any selection mouse up/drag events
// so we have to look if the mouse moved during this click to know
// if a selection occurred.
@@ -265,8 +266,7 @@
return;
}
// Returns true if something was selected, so stop propagation.
- if (attrs.track.onMouseClick(
- {x: e.layerX - TRACK_SHELL_WIDTH, y: e.layerY})) {
+ if (attrs.track.onMouseClick(currentTargetOffset(e))) {
e.stopPropagation();
}
raf.scheduleRedraw();
@@ -308,7 +308,7 @@
}
export interface TrackButtonAttrs {
- action: (e: PerfettoMouseEvent) => void;
+ action: (e: MouseEvent) => void;
i: string;
tooltip: string;
showButton: boolean;
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 2f3a2c6..0297f81 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -35,8 +35,6 @@
import {TrackGroupPanel} from './track_group_panel';
import {TrackPanel} from './track_panel';
-const SIDEBAR_WIDTH = 256;
-
const OVERVIEW_PANEL_FLAG = featureFlags.register({
id: 'overviewVisible',
name: 'Overview Panel',
@@ -119,7 +117,6 @@
this.zoomContent = new PanAndZoomHandler({
element: panZoomEl,
- contentOffsetX: SIDEBAR_WIDTH,
onPanned: (pannedPx: number) => {
const {
visibleTimeScale,