xref: /aosp_15_r20/external/perfetto/ui/src/plugins/dev.perfetto.GpuByProcess/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2023 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {NUM_NULL, STR_NULL} from '../../trace_processor/query_result';
16import {Trace} from '../../public/trace';
17import {Slice} from '../../public/track';
18import {PerfettoPlugin} from '../../public/plugin';
19import {
20  NAMED_ROW,
21  NamedRow,
22  NamedSliceTrack,
23} from '../../components/tracks/named_slice_track';
24import {TrackNode} from '../../public/workspace';
25class GpuPidTrack extends NamedSliceTrack {
26  constructor(
27    trace: Trace,
28    uri: string,
29    protected readonly upid: number,
30  ) {
31    super(trace, uri);
32    this.upid = upid;
33  }
34
35  protected getRowSpec(): NamedRow {
36    return NAMED_ROW;
37  }
38
39  protected rowToSlice(row: NamedRow): Slice {
40    return this.rowToSliceBase(row);
41  }
42
43  getSqlSource(): string {
44    return `
45      SELECT *
46      FROM gpu_slice
47      WHERE upid = ${this.upid}
48    `;
49  }
50}
51
52export default class implements PerfettoPlugin {
53  static readonly id = 'dev.perfetto.GpuByProcess';
54  async onTraceLoad(ctx: Trace): Promise<void> {
55    // Find all unique upid values in gpu_slices and join with process table.
56    const results = await ctx.engine.query(`
57      WITH slice_upids AS (
58        SELECT DISTINCT upid FROM gpu_slice
59      )
60      SELECT upid, pid, name FROM slice_upids JOIN process USING (upid)
61    `);
62
63    const it = results.iter({
64      upid: NUM_NULL,
65      pid: NUM_NULL,
66      name: STR_NULL,
67    });
68
69    // For each upid, create a GpuPidTrack.
70    for (; it.valid(); it.next()) {
71      if (it.upid == null) {
72        continue;
73      }
74
75      const upid = it.upid;
76      let processName = 'Unknown';
77      if (it.name != null) {
78        processName = it.name;
79      } else if (it.pid != null) {
80        processName = `${it.pid}`;
81      }
82
83      const uri = `dev.perfetto.GpuByProcess#${upid}`;
84      const title = `GPU ${processName}`;
85      ctx.tracks.registerTrack({
86        uri,
87        title,
88        track: new GpuPidTrack(ctx, uri, upid),
89      });
90      const track = new TrackNode({uri, title});
91      ctx.workspace.addChildInOrder(track);
92    }
93  }
94}
95