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 { 16 LONG, 17 NUM, 18 NUM_NULL, 19 STR, 20 STR_NULL, 21} from '../../trace_processor/query_result'; 22import {Trace} from '../../public/trace'; 23import {PerfettoPlugin} from '../../public/plugin'; 24import {TrackNode} from '../../public/workspace'; 25import {DatasetSliceTrack} from '../../components/tracks/dataset_slice_track'; 26import {SourceDataset} from '../../trace_processor/dataset'; 27import {ThreadSliceDetailsPanel} from '../../components/details/thread_slice_details_tab'; 28 29export default class implements PerfettoPlugin { 30 static readonly id = 'dev.perfetto.GpuByProcess'; 31 async onTraceLoad(ctx: Trace): Promise<void> { 32 // Find all unique upid values in gpu_slices and join with process table. 33 const results = await ctx.engine.query(` 34 WITH slice_upids AS ( 35 SELECT DISTINCT upid FROM gpu_slice 36 ) 37 SELECT upid, pid, name FROM slice_upids JOIN process USING (upid) 38 `); 39 40 const it = results.iter({ 41 upid: NUM_NULL, 42 pid: NUM_NULL, 43 name: STR_NULL, 44 }); 45 46 // For each upid, create a GpuPidTrack. 47 for (; it.valid(); it.next()) { 48 if (it.upid == null) { 49 continue; 50 } 51 52 const upid = it.upid; 53 let processName = 'Unknown'; 54 if (it.name != null) { 55 processName = it.name; 56 } else if (it.pid != null) { 57 processName = `${it.pid}`; 58 } 59 60 const uri = `dev.perfetto.GpuByProcess#${upid}`; 61 const title = `GPU ${processName}`; 62 ctx.tracks.registerTrack({ 63 uri, 64 title, 65 track: new DatasetSliceTrack({ 66 trace: ctx, 67 uri, 68 dataset: new SourceDataset({ 69 src: 'gpu_slice', 70 schema: { 71 id: NUM, 72 name: STR, 73 ts: LONG, 74 dur: LONG, 75 depth: NUM, 76 upid: NUM, 77 }, 78 filter: { 79 col: 'upid', 80 eq: upid, 81 }, 82 }), 83 detailsPanel: () => new ThreadSliceDetailsPanel(ctx), 84 }), 85 }); 86 const track = new TrackNode({uri, title}); 87 ctx.workspace.addChildInOrder(track); 88 } 89 } 90} 91