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 NUM_NULL, 17 Plugin, 18 PluginContextTrace, 19 PluginDescriptor, 20 STR_NULL, 21} from '../../public'; 22import {NamedSliceTrack} from '../../frontend/named_slice_track'; 23import {NewTrackArgs} from '../../frontend/track'; 24 25class GpuPidTrack extends NamedSliceTrack { 26 upid: number; 27 28 constructor(args: NewTrackArgs, upid: number) { 29 super(args); 30 this.upid = upid; 31 } 32 33 getSqlSource(): string { 34 return ` 35 SELECT * 36 FROM gpu_slice 37 WHERE upid = ${this.upid} 38 `; 39 } 40} 41 42class GpuByProcess implements Plugin { 43 async onTraceLoad(ctx: PluginContextTrace): Promise<void> { 44 // Find all unique upid values in gpu_slices and join with process table. 45 const results = await ctx.engine.query(` 46 WITH slice_upids AS ( 47 SELECT DISTINCT upid FROM gpu_slice 48 ) 49 SELECT upid, pid, name FROM slice_upids JOIN process USING (upid) 50 `); 51 52 const it = results.iter({ 53 upid: NUM_NULL, 54 pid: NUM_NULL, 55 name: STR_NULL, 56 }); 57 58 // For each upid, create a GpuPidTrack. 59 for (; it.valid(); it.next()) { 60 if (it.upid == null) { 61 continue; 62 } 63 64 const upid = it.upid; 65 let processName = 'Unknown'; 66 if (it.name != null) { 67 processName = it.name; 68 } else if (it.pid != null) { 69 processName = `${it.pid}`; 70 } 71 72 ctx.registerStaticTrack({ 73 uri: `dev.perfetto.GpuByProcess#${upid}`, 74 displayName: `GPU ${processName}`, 75 trackFactory: ({trackKey}) => { 76 return new GpuPidTrack({engine: ctx.engine, trackKey}, upid); 77 }, 78 }); 79 } 80 } 81 82 async onTraceUnload(_: PluginContextTrace): Promise<void> {} 83} 84 85export const plugin: PluginDescriptor = { 86 pluginId: 'dev.perfetto.GpuByProcess', 87 plugin: GpuByProcess, 88}; 89