blob: 4db962065e991a4d0ec5955abce9e992ae5fc081 [file] [log] [blame]
// 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 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.
import {v4 as uuidv4} from 'uuid';
import {Engine} from '../../common/engine';
import {
generateSqlWithInternalLayout,
} from '../../common/internal_layout_utils';
import {PrimaryTrackSortKey, SCROLLING_TRACK_GROUP} from '../../common/state';
import {
NamedSliceTrack,
NamedSliceTrackTypes,
} from '../../frontend/named_slice_track';
import {NewTrackArgs, Track} from '../../frontend/track';
import {DecideTracksResult} from '../chrome_scroll_jank';
export interface EventLatencyTrackTypes extends NamedSliceTrackTypes {
config: {baseTable: string;}
}
export class EventLatencyTrack extends NamedSliceTrack<EventLatencyTrackTypes> {
static readonly kind = 'org.chromium.ScrollJank.event_latencies';
static create(args: NewTrackArgs): Track {
return new EventLatencyTrack(args);
}
constructor(args: NewTrackArgs) {
super(args);
}
async initSqlTable(tableName: string) {
const sql =
`CREATE VIEW ${tableName} AS SELECT * FROM ${this.config.baseTable}`;
await this.engine.query(sql);
}
// At the moment we will just display the slice details. However, on select,
// this behavior should be customized to show jank-related data.
}
export async function addLatencyTracks(engine: Engine):
Promise<DecideTracksResult> {
const result: DecideTracksResult = {
tracksToAdd: [],
};
const subTableSql = generateSqlWithInternalLayout({
columns: ['id', 'ts', 'dur', 'track_id', 'name'],
sourceTable: 'slice',
ts: 'ts',
dur: 'dur',
whereClause: `
EXTRACT_ARG(arg_set_id, 'event_latency.event_type') IN (
'FIRST_GESTURE_SCROLL_UPDATE',
'GESTURE_SCROLL_UPDATE',
'INERTIAL_GESTURE_SCROLL_UPDATE')
AND HAS_DESCENDANT_SLICE_WITH_NAME(
id,
'SubmitCompositorFrameToPresentationCompositorFrame')`,
});
// Table name must be unique - it cannot include '-' characters or begin with
// a numeric value.
const baseTable =
`table_${uuidv4().split('-').join('_')}_janky_event_latencies_v2`;
const tableDefSql = `CREATE TABLE ${baseTable} AS
WITH event_latencies AS (
${subTableSql}
), latency_stages AS (
SELECT
d.id,
d.ts,
d.dur,
d.track_id,
d.name,
d.depth,
min(a.id) AS parent_id
FROM slice s
JOIN descendant_slice(s.id) d
JOIN ancestor_slice(d.id) a
WHERE s.id IN (SELECT id FROM event_latencies)
GROUP BY d.id, d.ts, d.dur, d.track_id, d.name, d.parent_id, d.depth)
SELECT
id,
ts,
dur,
CASE
WHEN id IN (
SELECT id FROM chrome_janky_event_latencies_v2)
THEN 'Janky EventLatency'
ELSE name
END
AS name,
depth * 3 AS depth
FROM event_latencies
UNION ALL
SELECT
ls.id,
ls.ts,
ls.dur,
ls.name,
depth + (
(SELECT depth FROM event_latencies
WHERE id = ls.parent_id LIMIT 1) * 3) AS depth
FROM latency_stages ls;`;
await engine.query(`SELECT IMPORT('chrome.chrome_scroll_janks')`);
await engine.query(tableDefSql);
result.tracksToAdd.push({
id: uuidv4(),
engineId: engine.id,
kind: EventLatencyTrack.kind,
trackSortKey: PrimaryTrackSortKey.NULL_TRACK,
name: 'Chrome Input Event Latencies',
config: {baseTable: baseTable},
trackGroup: SCROLLING_TRACK_GROUP,
});
return result;
}