xref: /aosp_15_r20/external/perfetto/ui/src/public/track.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2024 The Android Open Source Project
2*6dbdd20aSAndroid Build Coastguard Worker//
3*6dbdd20aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*6dbdd20aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*6dbdd20aSAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*6dbdd20aSAndroid Build Coastguard Worker//
7*6dbdd20aSAndroid Build Coastguard Worker//      http://www.apache.org/licenses/LICENSE-2.0
8*6dbdd20aSAndroid Build Coastguard Worker//
9*6dbdd20aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*6dbdd20aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*6dbdd20aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*6dbdd20aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*6dbdd20aSAndroid Build Coastguard Worker// limitations under the License.
14*6dbdd20aSAndroid Build Coastguard Worker
15*6dbdd20aSAndroid Build Coastguard Workerimport m from 'mithril';
16*6dbdd20aSAndroid Build Coastguard Workerimport {duration, time} from '../base/time';
17*6dbdd20aSAndroid Build Coastguard Workerimport {Size2D, VerticalBounds} from '../base/geom';
18*6dbdd20aSAndroid Build Coastguard Workerimport {TimeScale} from '../base/time_scale';
19*6dbdd20aSAndroid Build Coastguard Workerimport {HighPrecisionTimeSpan} from '../base/high_precision_time_span';
20*6dbdd20aSAndroid Build Coastguard Workerimport {ColorScheme} from './color_scheme';
21*6dbdd20aSAndroid Build Coastguard Workerimport {TrackEventDetailsPanel} from './details_panel';
22*6dbdd20aSAndroid Build Coastguard Workerimport {TrackEventDetails, TrackEventSelection} from './selection';
23*6dbdd20aSAndroid Build Coastguard Workerimport {Dataset} from '../trace_processor/dataset';
24*6dbdd20aSAndroid Build Coastguard Worker
25*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackManager {
26*6dbdd20aSAndroid Build Coastguard Worker  /**
27*6dbdd20aSAndroid Build Coastguard Worker   * Register a new track against a unique key known as a URI. The track is not
28*6dbdd20aSAndroid Build Coastguard Worker   * shown by default and callers need to either manually add it to a
29*6dbdd20aSAndroid Build Coastguard Worker   * Workspace or use registerTrackAndShowOnTraceLoad() below.
30*6dbdd20aSAndroid Build Coastguard Worker   */
31*6dbdd20aSAndroid Build Coastguard Worker  registerTrack(trackDesc: TrackDescriptor): void;
32*6dbdd20aSAndroid Build Coastguard Worker
33*6dbdd20aSAndroid Build Coastguard Worker  findTrack(
34*6dbdd20aSAndroid Build Coastguard Worker    predicate: (desc: TrackDescriptor) => boolean | undefined,
35*6dbdd20aSAndroid Build Coastguard Worker  ): TrackDescriptor | undefined;
36*6dbdd20aSAndroid Build Coastguard Worker
37*6dbdd20aSAndroid Build Coastguard Worker  getAllTracks(): TrackDescriptor[];
38*6dbdd20aSAndroid Build Coastguard Worker
39*6dbdd20aSAndroid Build Coastguard Worker  getTrack(uri: string): TrackDescriptor | undefined;
40*6dbdd20aSAndroid Build Coastguard Worker}
41*6dbdd20aSAndroid Build Coastguard Worker
42*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackContext {
43*6dbdd20aSAndroid Build Coastguard Worker  // This track's URI, used for making selections et al.
44*6dbdd20aSAndroid Build Coastguard Worker  readonly trackUri: string;
45*6dbdd20aSAndroid Build Coastguard Worker}
46*6dbdd20aSAndroid Build Coastguard Worker
47*6dbdd20aSAndroid Build Coastguard Worker/**
48*6dbdd20aSAndroid Build Coastguard Worker * Contextual information about the track passed to track lifecycle hooks &
49*6dbdd20aSAndroid Build Coastguard Worker * render hooks with additional information about the timeline/canvas.
50*6dbdd20aSAndroid Build Coastguard Worker */
51*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackRenderContext extends TrackContext {
52*6dbdd20aSAndroid Build Coastguard Worker  /**
53*6dbdd20aSAndroid Build Coastguard Worker   * The time span of the visible window.
54*6dbdd20aSAndroid Build Coastguard Worker   */
55*6dbdd20aSAndroid Build Coastguard Worker  readonly visibleWindow: HighPrecisionTimeSpan;
56*6dbdd20aSAndroid Build Coastguard Worker
57*6dbdd20aSAndroid Build Coastguard Worker  /**
58*6dbdd20aSAndroid Build Coastguard Worker   * The dimensions of the track on the canvas in pixels.
59*6dbdd20aSAndroid Build Coastguard Worker   */
60*6dbdd20aSAndroid Build Coastguard Worker  readonly size: Size2D;
61*6dbdd20aSAndroid Build Coastguard Worker
62*6dbdd20aSAndroid Build Coastguard Worker  /**
63*6dbdd20aSAndroid Build Coastguard Worker   * Suggested data resolution.
64*6dbdd20aSAndroid Build Coastguard Worker   *
65*6dbdd20aSAndroid Build Coastguard Worker   * This number is the number of time units that corresponds to 1 pixel on the
66*6dbdd20aSAndroid Build Coastguard Worker   * screen, rounded down to the nearest power of 2. The minimum value is 1.
67*6dbdd20aSAndroid Build Coastguard Worker   *
68*6dbdd20aSAndroid Build Coastguard Worker   * It's up to the track whether it would like to use this resolution or
69*6dbdd20aSAndroid Build Coastguard Worker   * calculate their own based on the timespan and the track dimensions.
70*6dbdd20aSAndroid Build Coastguard Worker   */
71*6dbdd20aSAndroid Build Coastguard Worker  readonly resolution: duration;
72*6dbdd20aSAndroid Build Coastguard Worker
73*6dbdd20aSAndroid Build Coastguard Worker  /**
74*6dbdd20aSAndroid Build Coastguard Worker   * Canvas context used for rendering.
75*6dbdd20aSAndroid Build Coastguard Worker   */
76*6dbdd20aSAndroid Build Coastguard Worker  readonly ctx: CanvasRenderingContext2D;
77*6dbdd20aSAndroid Build Coastguard Worker
78*6dbdd20aSAndroid Build Coastguard Worker  /**
79*6dbdd20aSAndroid Build Coastguard Worker   * A time scale used for translating between pixels and time.
80*6dbdd20aSAndroid Build Coastguard Worker   */
81*6dbdd20aSAndroid Build Coastguard Worker  readonly timescale: TimeScale;
82*6dbdd20aSAndroid Build Coastguard Worker}
83*6dbdd20aSAndroid Build Coastguard Worker
84*6dbdd20aSAndroid Build Coastguard Worker// A definition of a track, including a renderer implementation and metadata.
85*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackDescriptor {
86*6dbdd20aSAndroid Build Coastguard Worker  // A unique identifier for this track.
87*6dbdd20aSAndroid Build Coastguard Worker  readonly uri: string;
88*6dbdd20aSAndroid Build Coastguard Worker
89*6dbdd20aSAndroid Build Coastguard Worker  // A factory function returning a new track instance.
90*6dbdd20aSAndroid Build Coastguard Worker  readonly track: Track;
91*6dbdd20aSAndroid Build Coastguard Worker
92*6dbdd20aSAndroid Build Coastguard Worker  // Human readable title. Always displayed.
93*6dbdd20aSAndroid Build Coastguard Worker  readonly title: string;
94*6dbdd20aSAndroid Build Coastguard Worker
95*6dbdd20aSAndroid Build Coastguard Worker  // Human readable subtitle. Sometimes displayed if there is room.
96*6dbdd20aSAndroid Build Coastguard Worker  readonly subtitle?: string;
97*6dbdd20aSAndroid Build Coastguard Worker
98*6dbdd20aSAndroid Build Coastguard Worker  // Optional: A list of tags used for sorting, grouping and "chips".
99*6dbdd20aSAndroid Build Coastguard Worker  readonly tags?: TrackTags;
100*6dbdd20aSAndroid Build Coastguard Worker
101*6dbdd20aSAndroid Build Coastguard Worker  readonly chips?: ReadonlyArray<string>;
102*6dbdd20aSAndroid Build Coastguard Worker
103*6dbdd20aSAndroid Build Coastguard Worker  readonly pluginId?: string;
104*6dbdd20aSAndroid Build Coastguard Worker}
105*6dbdd20aSAndroid Build Coastguard Worker
106*6dbdd20aSAndroid Build Coastguard Worker/**
107*6dbdd20aSAndroid Build Coastguard Worker * Contextual information passed to mouse events.
108*6dbdd20aSAndroid Build Coastguard Worker */
109*6dbdd20aSAndroid Build Coastguard Workerexport interface TrackMouseEvent {
110*6dbdd20aSAndroid Build Coastguard Worker  /**
111*6dbdd20aSAndroid Build Coastguard Worker   * X coordinate of the mouse event w.r.t. the top-left of the track.
112*6dbdd20aSAndroid Build Coastguard Worker   */
113*6dbdd20aSAndroid Build Coastguard Worker  readonly x: number;
114*6dbdd20aSAndroid Build Coastguard Worker
115*6dbdd20aSAndroid Build Coastguard Worker  /**
116*6dbdd20aSAndroid Build Coastguard Worker   * Y coordinate of the mouse event w.r.t the top-left of the track.
117*6dbdd20aSAndroid Build Coastguard Worker   */
118*6dbdd20aSAndroid Build Coastguard Worker  readonly y: number;
119*6dbdd20aSAndroid Build Coastguard Worker
120*6dbdd20aSAndroid Build Coastguard Worker  /**
121*6dbdd20aSAndroid Build Coastguard Worker   * A time scale used for translating between pixels and time.
122*6dbdd20aSAndroid Build Coastguard Worker   */
123*6dbdd20aSAndroid Build Coastguard Worker  readonly timescale: TimeScale;
124*6dbdd20aSAndroid Build Coastguard Worker}
125*6dbdd20aSAndroid Build Coastguard Worker
126*6dbdd20aSAndroid Build Coastguard Workerexport interface Track {
127*6dbdd20aSAndroid Build Coastguard Worker  /**
128*6dbdd20aSAndroid Build Coastguard Worker   * Optional lifecycle hook called on the first render cycle. Should be used to
129*6dbdd20aSAndroid Build Coastguard Worker   * create any required resources.
130*6dbdd20aSAndroid Build Coastguard Worker   *
131*6dbdd20aSAndroid Build Coastguard Worker   * These lifecycle hooks are asynchronous, but they are run synchronously,
132*6dbdd20aSAndroid Build Coastguard Worker   * meaning that perfetto will wait for each one to complete before calling the
133*6dbdd20aSAndroid Build Coastguard Worker   * next one, so the user doesn't have to serialize these calls manually.
134*6dbdd20aSAndroid Build Coastguard Worker   *
135*6dbdd20aSAndroid Build Coastguard Worker   * Exactly when this hook is called is left purposely undefined. The only
136*6dbdd20aSAndroid Build Coastguard Worker   * guarantee is that it will be called exactly once before the first call to
137*6dbdd20aSAndroid Build Coastguard Worker   * onUpdate().
138*6dbdd20aSAndroid Build Coastguard Worker   *
139*6dbdd20aSAndroid Build Coastguard Worker   * Note: On the first render cycle, both onCreate and onUpdate are called one
140*6dbdd20aSAndroid Build Coastguard Worker   * after another.
141*6dbdd20aSAndroid Build Coastguard Worker   */
142*6dbdd20aSAndroid Build Coastguard Worker  onCreate?(ctx: TrackContext): Promise<void>;
143*6dbdd20aSAndroid Build Coastguard Worker
144*6dbdd20aSAndroid Build Coastguard Worker  /**
145*6dbdd20aSAndroid Build Coastguard Worker   * Optional lifecycle hook called on every render cycle.
146*6dbdd20aSAndroid Build Coastguard Worker   *
147*6dbdd20aSAndroid Build Coastguard Worker   * The track should inspect things like the visible window, track size, and
148*6dbdd20aSAndroid Build Coastguard Worker   * resolution to work out whether any data needs to be reloaded based on these
149*6dbdd20aSAndroid Build Coastguard Worker   * properties and perform a reload.
150*6dbdd20aSAndroid Build Coastguard Worker   */
151*6dbdd20aSAndroid Build Coastguard Worker  onUpdate?(ctx: TrackRenderContext): Promise<void>;
152*6dbdd20aSAndroid Build Coastguard Worker
153*6dbdd20aSAndroid Build Coastguard Worker  /**
154*6dbdd20aSAndroid Build Coastguard Worker   * Optional lifecycle hook called when the track is no longer visible. Should
155*6dbdd20aSAndroid Build Coastguard Worker   * be used to clear up any resources.
156*6dbdd20aSAndroid Build Coastguard Worker   */
157*6dbdd20aSAndroid Build Coastguard Worker  onDestroy?(): Promise<void>;
158*6dbdd20aSAndroid Build Coastguard Worker
159*6dbdd20aSAndroid Build Coastguard Worker  /**
160*6dbdd20aSAndroid Build Coastguard Worker   * Required method used to render the track's content to the canvas, called
161*6dbdd20aSAndroid Build Coastguard Worker   * synchronously on every render cycle.
162*6dbdd20aSAndroid Build Coastguard Worker   */
163*6dbdd20aSAndroid Build Coastguard Worker  render(ctx: TrackRenderContext): void;
164*6dbdd20aSAndroid Build Coastguard Worker  onFullRedraw?(): void;
165*6dbdd20aSAndroid Build Coastguard Worker
166*6dbdd20aSAndroid Build Coastguard Worker  /**
167*6dbdd20aSAndroid Build Coastguard Worker   * Return the vertical bounds (top & bottom) of a slice were it to be rendered
168*6dbdd20aSAndroid Build Coastguard Worker   * at a specific depth, given the slice height and padding/spacing that this
169*6dbdd20aSAndroid Build Coastguard Worker   * track uses.
170*6dbdd20aSAndroid Build Coastguard Worker   */
171*6dbdd20aSAndroid Build Coastguard Worker  getSliceVerticalBounds?(depth: number): VerticalBounds | undefined;
172*6dbdd20aSAndroid Build Coastguard Worker  getHeight(): number;
173*6dbdd20aSAndroid Build Coastguard Worker  getTrackShellButtons?(): m.Children;
174*6dbdd20aSAndroid Build Coastguard Worker  onMouseMove?(event: TrackMouseEvent): void;
175*6dbdd20aSAndroid Build Coastguard Worker  onMouseClick?(event: TrackMouseEvent): boolean;
176*6dbdd20aSAndroid Build Coastguard Worker  onMouseOut?(): void;
177*6dbdd20aSAndroid Build Coastguard Worker
178*6dbdd20aSAndroid Build Coastguard Worker  /**
179*6dbdd20aSAndroid Build Coastguard Worker   * Optional: Returns a dataset that represents the events displayed on this
180*6dbdd20aSAndroid Build Coastguard Worker   * track.
181*6dbdd20aSAndroid Build Coastguard Worker   */
182*6dbdd20aSAndroid Build Coastguard Worker  getDataset?(): Dataset | undefined;
183*6dbdd20aSAndroid Build Coastguard Worker
184*6dbdd20aSAndroid Build Coastguard Worker  /**
185*6dbdd20aSAndroid Build Coastguard Worker   * Optional: Get details of a track event given by eventId on this track.
186*6dbdd20aSAndroid Build Coastguard Worker   */
187*6dbdd20aSAndroid Build Coastguard Worker  getSelectionDetails?(eventId: number): Promise<TrackEventDetails | undefined>;
188*6dbdd20aSAndroid Build Coastguard Worker
189*6dbdd20aSAndroid Build Coastguard Worker  // Optional: A factory that returns a details panel object for a given track
190*6dbdd20aSAndroid Build Coastguard Worker  // event selection. This is called each time the selection is changed (and the
191*6dbdd20aSAndroid Build Coastguard Worker  // selection is relevant to this track).
192*6dbdd20aSAndroid Build Coastguard Worker  detailsPanel?(sel: TrackEventSelection): TrackEventDetailsPanel;
193*6dbdd20aSAndroid Build Coastguard Worker}
194*6dbdd20aSAndroid Build Coastguard Worker
195*6dbdd20aSAndroid Build Coastguard Worker// An set of key/value pairs describing a given track. These are used for
196*6dbdd20aSAndroid Build Coastguard Worker// selecting tracks to pin/unpin, diplsaying "chips" in the track shell, and
197*6dbdd20aSAndroid Build Coastguard Worker// (in future) the sorting and grouping of tracks.
198*6dbdd20aSAndroid Build Coastguard Worker// We define a handful of well known fields, and the rest are arbitrary key-
199*6dbdd20aSAndroid Build Coastguard Worker// value pairs.
200*6dbdd20aSAndroid Build Coastguard Workerexport type TrackTags = Partial<WellKnownTrackTags> & {
201*6dbdd20aSAndroid Build Coastguard Worker  // There may be arbitrary other key/value pairs.
202*6dbdd20aSAndroid Build Coastguard Worker  [key: string]:
203*6dbdd20aSAndroid Build Coastguard Worker    | undefined
204*6dbdd20aSAndroid Build Coastguard Worker    | string
205*6dbdd20aSAndroid Build Coastguard Worker    | number
206*6dbdd20aSAndroid Build Coastguard Worker    | boolean
207*6dbdd20aSAndroid Build Coastguard Worker    | ReadonlyArray<string>
208*6dbdd20aSAndroid Build Coastguard Worker    | ReadonlyArray<number>;
209*6dbdd20aSAndroid Build Coastguard Worker};
210*6dbdd20aSAndroid Build Coastguard Worker
211*6dbdd20aSAndroid Build Coastguard Workerinterface WellKnownTrackTags {
212*6dbdd20aSAndroid Build Coastguard Worker  // The track "kind", used by various subsystems e.g. aggregation controllers.
213*6dbdd20aSAndroid Build Coastguard Worker  // This is where "XXX_TRACK_KIND" values should be placed.
214*6dbdd20aSAndroid Build Coastguard Worker  // TODO(stevegolton): This will be deprecated once we handle group selections
215*6dbdd20aSAndroid Build Coastguard Worker  // in a more generic way - i.e. EventSet.
216*6dbdd20aSAndroid Build Coastguard Worker  kind: string;
217*6dbdd20aSAndroid Build Coastguard Worker
218*6dbdd20aSAndroid Build Coastguard Worker  // Optional: list of track IDs represented by this trace.
219*6dbdd20aSAndroid Build Coastguard Worker  // This list is used for participation in track indexing by track ID.
220*6dbdd20aSAndroid Build Coastguard Worker  // This index is used by various subsystems to find links between tracks based
221*6dbdd20aSAndroid Build Coastguard Worker  // on the track IDs used by trace processor.
222*6dbdd20aSAndroid Build Coastguard Worker  trackIds: ReadonlyArray<number>;
223*6dbdd20aSAndroid Build Coastguard Worker
224*6dbdd20aSAndroid Build Coastguard Worker  // Optional: The CPU number associated with this track.
225*6dbdd20aSAndroid Build Coastguard Worker  cpu: number;
226*6dbdd20aSAndroid Build Coastguard Worker
227*6dbdd20aSAndroid Build Coastguard Worker  // Optional: The UTID associated with this track.
228*6dbdd20aSAndroid Build Coastguard Worker  utid: number;
229*6dbdd20aSAndroid Build Coastguard Worker
230*6dbdd20aSAndroid Build Coastguard Worker  // Optional: The UPID associated with this track.
231*6dbdd20aSAndroid Build Coastguard Worker  upid: number;
232*6dbdd20aSAndroid Build Coastguard Worker
233*6dbdd20aSAndroid Build Coastguard Worker  // Used for sorting and grouping
234*6dbdd20aSAndroid Build Coastguard Worker  scope: string;
235*6dbdd20aSAndroid Build Coastguard Worker
236*6dbdd20aSAndroid Build Coastguard Worker  // Group name, used as a hint to ask track decider to put this in a group
237*6dbdd20aSAndroid Build Coastguard Worker  groupName: string;
238*6dbdd20aSAndroid Build Coastguard Worker}
239*6dbdd20aSAndroid Build Coastguard Worker
240*6dbdd20aSAndroid Build Coastguard Workerexport interface Slice {
241*6dbdd20aSAndroid Build Coastguard Worker  // These properties are updated only once per query result when the Slice
242*6dbdd20aSAndroid Build Coastguard Worker  // object is created and don't change afterwards.
243*6dbdd20aSAndroid Build Coastguard Worker  readonly id: number;
244*6dbdd20aSAndroid Build Coastguard Worker  readonly startNs: time;
245*6dbdd20aSAndroid Build Coastguard Worker  readonly endNs: time;
246*6dbdd20aSAndroid Build Coastguard Worker  readonly durNs: duration;
247*6dbdd20aSAndroid Build Coastguard Worker  readonly ts: time;
248*6dbdd20aSAndroid Build Coastguard Worker  readonly dur: duration;
249*6dbdd20aSAndroid Build Coastguard Worker  readonly depth: number;
250*6dbdd20aSAndroid Build Coastguard Worker  readonly flags: number;
251*6dbdd20aSAndroid Build Coastguard Worker
252*6dbdd20aSAndroid Build Coastguard Worker  // Each slice can represent some extra numerical information by rendering a
253*6dbdd20aSAndroid Build Coastguard Worker  // portion of the slice with a lighter tint.
254*6dbdd20aSAndroid Build Coastguard Worker  // |fillRatio\ describes the ratio of the normal area to the tinted area
255*6dbdd20aSAndroid Build Coastguard Worker  // width of the slice, normalized between 0.0 -> 1.0.
256*6dbdd20aSAndroid Build Coastguard Worker  // 0.0 means the whole slice is tinted.
257*6dbdd20aSAndroid Build Coastguard Worker  // 1.0 means none of the slice is tinted.
258*6dbdd20aSAndroid Build Coastguard Worker  // E.g. If |fillRatio| = 0.65 the slice will be rendered like this:
259*6dbdd20aSAndroid Build Coastguard Worker  // [############|*******]
260*6dbdd20aSAndroid Build Coastguard Worker  // ^------------^-------^
261*6dbdd20aSAndroid Build Coastguard Worker  //     Normal     Light
262*6dbdd20aSAndroid Build Coastguard Worker  readonly fillRatio: number;
263*6dbdd20aSAndroid Build Coastguard Worker
264*6dbdd20aSAndroid Build Coastguard Worker  // These can be changed by the Impl.
265*6dbdd20aSAndroid Build Coastguard Worker  title: string;
266*6dbdd20aSAndroid Build Coastguard Worker  subTitle: string;
267*6dbdd20aSAndroid Build Coastguard Worker  colorScheme: ColorScheme;
268*6dbdd20aSAndroid Build Coastguard Worker  isHighlighted: boolean;
269*6dbdd20aSAndroid Build Coastguard Worker}
270