1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2021 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 { 16*6dbdd20aSAndroid Build Coastguard Worker ACTUAL_FRAMES_SLICE_TRACK_KIND, 17*6dbdd20aSAndroid Build Coastguard Worker EXPECTED_FRAMES_SLICE_TRACK_KIND, 18*6dbdd20aSAndroid Build Coastguard Worker} from '../../public/track_kinds'; 19*6dbdd20aSAndroid Build Coastguard Workerimport {Trace} from '../../public/trace'; 20*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin'; 21*6dbdd20aSAndroid Build Coastguard Workerimport {getTrackName} from '../../public/utils'; 22*6dbdd20aSAndroid Build Coastguard Workerimport {TrackNode} from '../../public/workspace'; 23*6dbdd20aSAndroid Build Coastguard Workerimport {NUM, NUM_NULL, STR, STR_NULL} from '../../trace_processor/query_result'; 24*6dbdd20aSAndroid Build Coastguard Workerimport {ActualFramesTrack} from './actual_frames_track'; 25*6dbdd20aSAndroid Build Coastguard Workerimport {ExpectedFramesTrack} from './expected_frames_track'; 26*6dbdd20aSAndroid Build Coastguard Workerimport {FrameSelectionAggregator} from './frame_selection_aggregator'; 27*6dbdd20aSAndroid Build Coastguard Workerimport ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups'; 28*6dbdd20aSAndroid Build Coastguard Worker 29*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin { 30*6dbdd20aSAndroid Build Coastguard Worker static readonly id = 'dev.perfetto.Frames'; 31*6dbdd20aSAndroid Build Coastguard Worker static readonly dependencies = [ProcessThreadGroupsPlugin]; 32*6dbdd20aSAndroid Build Coastguard Worker 33*6dbdd20aSAndroid Build Coastguard Worker async onTraceLoad(ctx: Trace): Promise<void> { 34*6dbdd20aSAndroid Build Coastguard Worker this.addExpectedFrames(ctx); 35*6dbdd20aSAndroid Build Coastguard Worker this.addActualFrames(ctx); 36*6dbdd20aSAndroid Build Coastguard Worker ctx.selection.registerAreaSelectionAggregator( 37*6dbdd20aSAndroid Build Coastguard Worker new FrameSelectionAggregator(), 38*6dbdd20aSAndroid Build Coastguard Worker ); 39*6dbdd20aSAndroid Build Coastguard Worker } 40*6dbdd20aSAndroid Build Coastguard Worker 41*6dbdd20aSAndroid Build Coastguard Worker async addExpectedFrames(ctx: Trace): Promise<void> { 42*6dbdd20aSAndroid Build Coastguard Worker const {engine} = ctx; 43*6dbdd20aSAndroid Build Coastguard Worker const result = await engine.query(` 44*6dbdd20aSAndroid Build Coastguard Worker select 45*6dbdd20aSAndroid Build Coastguard Worker upid, 46*6dbdd20aSAndroid Build Coastguard Worker t.name as trackName, 47*6dbdd20aSAndroid Build Coastguard Worker t.track_ids as trackIds, 48*6dbdd20aSAndroid Build Coastguard Worker process.name as processName, 49*6dbdd20aSAndroid Build Coastguard Worker process.pid as pid, 50*6dbdd20aSAndroid Build Coastguard Worker __max_layout_depth(t.track_count, t.track_ids) as maxDepth 51*6dbdd20aSAndroid Build Coastguard Worker from _process_track_summary_by_upid_and_parent_id_and_name t 52*6dbdd20aSAndroid Build Coastguard Worker join process using(upid) 53*6dbdd20aSAndroid Build Coastguard Worker where t.name = "Expected Timeline" 54*6dbdd20aSAndroid Build Coastguard Worker `); 55*6dbdd20aSAndroid Build Coastguard Worker 56*6dbdd20aSAndroid Build Coastguard Worker const it = result.iter({ 57*6dbdd20aSAndroid Build Coastguard Worker upid: NUM, 58*6dbdd20aSAndroid Build Coastguard Worker trackName: STR_NULL, 59*6dbdd20aSAndroid Build Coastguard Worker trackIds: STR, 60*6dbdd20aSAndroid Build Coastguard Worker processName: STR_NULL, 61*6dbdd20aSAndroid Build Coastguard Worker pid: NUM_NULL, 62*6dbdd20aSAndroid Build Coastguard Worker maxDepth: NUM, 63*6dbdd20aSAndroid Build Coastguard Worker }); 64*6dbdd20aSAndroid Build Coastguard Worker 65*6dbdd20aSAndroid Build Coastguard Worker for (; it.valid(); it.next()) { 66*6dbdd20aSAndroid Build Coastguard Worker const upid = it.upid; 67*6dbdd20aSAndroid Build Coastguard Worker const trackName = it.trackName; 68*6dbdd20aSAndroid Build Coastguard Worker const rawTrackIds = it.trackIds; 69*6dbdd20aSAndroid Build Coastguard Worker const trackIds = rawTrackIds.split(',').map((v) => Number(v)); 70*6dbdd20aSAndroid Build Coastguard Worker const processName = it.processName; 71*6dbdd20aSAndroid Build Coastguard Worker const pid = it.pid; 72*6dbdd20aSAndroid Build Coastguard Worker const maxDepth = it.maxDepth; 73*6dbdd20aSAndroid Build Coastguard Worker 74*6dbdd20aSAndroid Build Coastguard Worker const title = getTrackName({ 75*6dbdd20aSAndroid Build Coastguard Worker name: trackName, 76*6dbdd20aSAndroid Build Coastguard Worker upid, 77*6dbdd20aSAndroid Build Coastguard Worker pid, 78*6dbdd20aSAndroid Build Coastguard Worker processName, 79*6dbdd20aSAndroid Build Coastguard Worker kind: 'ExpectedFrames', 80*6dbdd20aSAndroid Build Coastguard Worker }); 81*6dbdd20aSAndroid Build Coastguard Worker 82*6dbdd20aSAndroid Build Coastguard Worker const uri = `/process_${upid}/expected_frames`; 83*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 84*6dbdd20aSAndroid Build Coastguard Worker uri, 85*6dbdd20aSAndroid Build Coastguard Worker title, 86*6dbdd20aSAndroid Build Coastguard Worker track: new ExpectedFramesTrack(ctx, maxDepth, uri, trackIds), 87*6dbdd20aSAndroid Build Coastguard Worker tags: { 88*6dbdd20aSAndroid Build Coastguard Worker trackIds, 89*6dbdd20aSAndroid Build Coastguard Worker upid, 90*6dbdd20aSAndroid Build Coastguard Worker kind: EXPECTED_FRAMES_SLICE_TRACK_KIND, 91*6dbdd20aSAndroid Build Coastguard Worker }, 92*6dbdd20aSAndroid Build Coastguard Worker }); 93*6dbdd20aSAndroid Build Coastguard Worker const group = ctx.plugins 94*6dbdd20aSAndroid Build Coastguard Worker .getPlugin(ProcessThreadGroupsPlugin) 95*6dbdd20aSAndroid Build Coastguard Worker .getGroupForProcess(upid); 96*6dbdd20aSAndroid Build Coastguard Worker const track = new TrackNode({uri, title, sortOrder: -50}); 97*6dbdd20aSAndroid Build Coastguard Worker group?.addChildInOrder(track); 98*6dbdd20aSAndroid Build Coastguard Worker } 99*6dbdd20aSAndroid Build Coastguard Worker } 100*6dbdd20aSAndroid Build Coastguard Worker 101*6dbdd20aSAndroid Build Coastguard Worker async addActualFrames(ctx: Trace): Promise<void> { 102*6dbdd20aSAndroid Build Coastguard Worker const {engine} = ctx; 103*6dbdd20aSAndroid Build Coastguard Worker const result = await engine.query(` 104*6dbdd20aSAndroid Build Coastguard Worker select 105*6dbdd20aSAndroid Build Coastguard Worker upid, 106*6dbdd20aSAndroid Build Coastguard Worker t.name as trackName, 107*6dbdd20aSAndroid Build Coastguard Worker t.track_ids as trackIds, 108*6dbdd20aSAndroid Build Coastguard Worker process.name as processName, 109*6dbdd20aSAndroid Build Coastguard Worker process.pid as pid, 110*6dbdd20aSAndroid Build Coastguard Worker __max_layout_depth(t.track_count, t.track_ids) as maxDepth 111*6dbdd20aSAndroid Build Coastguard Worker from _process_track_summary_by_upid_and_parent_id_and_name t 112*6dbdd20aSAndroid Build Coastguard Worker join process using(upid) 113*6dbdd20aSAndroid Build Coastguard Worker where t.name = "Actual Timeline" 114*6dbdd20aSAndroid Build Coastguard Worker `); 115*6dbdd20aSAndroid Build Coastguard Worker 116*6dbdd20aSAndroid Build Coastguard Worker const it = result.iter({ 117*6dbdd20aSAndroid Build Coastguard Worker upid: NUM, 118*6dbdd20aSAndroid Build Coastguard Worker trackName: STR_NULL, 119*6dbdd20aSAndroid Build Coastguard Worker trackIds: STR, 120*6dbdd20aSAndroid Build Coastguard Worker processName: STR_NULL, 121*6dbdd20aSAndroid Build Coastguard Worker pid: NUM_NULL, 122*6dbdd20aSAndroid Build Coastguard Worker maxDepth: NUM_NULL, 123*6dbdd20aSAndroid Build Coastguard Worker }); 124*6dbdd20aSAndroid Build Coastguard Worker for (; it.valid(); it.next()) { 125*6dbdd20aSAndroid Build Coastguard Worker const upid = it.upid; 126*6dbdd20aSAndroid Build Coastguard Worker const trackName = it.trackName; 127*6dbdd20aSAndroid Build Coastguard Worker const rawTrackIds = it.trackIds; 128*6dbdd20aSAndroid Build Coastguard Worker const trackIds = rawTrackIds.split(',').map((v) => Number(v)); 129*6dbdd20aSAndroid Build Coastguard Worker const processName = it.processName; 130*6dbdd20aSAndroid Build Coastguard Worker const pid = it.pid; 131*6dbdd20aSAndroid Build Coastguard Worker const maxDepth = it.maxDepth; 132*6dbdd20aSAndroid Build Coastguard Worker 133*6dbdd20aSAndroid Build Coastguard Worker if (maxDepth === null) { 134*6dbdd20aSAndroid Build Coastguard Worker // If there are no slices in this track, skip it. 135*6dbdd20aSAndroid Build Coastguard Worker continue; 136*6dbdd20aSAndroid Build Coastguard Worker } 137*6dbdd20aSAndroid Build Coastguard Worker 138*6dbdd20aSAndroid Build Coastguard Worker const kind = 'ActualFrames'; 139*6dbdd20aSAndroid Build Coastguard Worker const title = getTrackName({ 140*6dbdd20aSAndroid Build Coastguard Worker name: trackName, 141*6dbdd20aSAndroid Build Coastguard Worker upid, 142*6dbdd20aSAndroid Build Coastguard Worker pid, 143*6dbdd20aSAndroid Build Coastguard Worker processName, 144*6dbdd20aSAndroid Build Coastguard Worker kind, 145*6dbdd20aSAndroid Build Coastguard Worker }); 146*6dbdd20aSAndroid Build Coastguard Worker 147*6dbdd20aSAndroid Build Coastguard Worker const uri = `/process_${upid}/actual_frames`; 148*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 149*6dbdd20aSAndroid Build Coastguard Worker uri, 150*6dbdd20aSAndroid Build Coastguard Worker title, 151*6dbdd20aSAndroid Build Coastguard Worker track: new ActualFramesTrack(ctx, maxDepth, uri, trackIds), 152*6dbdd20aSAndroid Build Coastguard Worker tags: { 153*6dbdd20aSAndroid Build Coastguard Worker upid, 154*6dbdd20aSAndroid Build Coastguard Worker trackIds, 155*6dbdd20aSAndroid Build Coastguard Worker kind: ACTUAL_FRAMES_SLICE_TRACK_KIND, 156*6dbdd20aSAndroid Build Coastguard Worker }, 157*6dbdd20aSAndroid Build Coastguard Worker }); 158*6dbdd20aSAndroid Build Coastguard Worker const group = ctx.plugins 159*6dbdd20aSAndroid Build Coastguard Worker .getPlugin(ProcessThreadGroupsPlugin) 160*6dbdd20aSAndroid Build Coastguard Worker .getGroupForProcess(upid); 161*6dbdd20aSAndroid Build Coastguard Worker const track = new TrackNode({uri, title, sortOrder: -50}); 162*6dbdd20aSAndroid Build Coastguard Worker group?.addChildInOrder(track); 163*6dbdd20aSAndroid Build Coastguard Worker } 164*6dbdd20aSAndroid Build Coastguard Worker } 165*6dbdd20aSAndroid Build Coastguard Worker} 166