1// Copyright (C) 2024 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 m from 'mithril'; 16import {Button} from '../../widgets/button'; 17import {Icons} from '../../base/semantic_icons'; 18import {uuidv4Sql} from '../../base/uuid'; 19import {createView} from '../../trace_processor/sql_utils'; 20import {Trace} from '../../public/trace'; 21import {DatasetSliceTrack} from './dataset_slice_track'; 22import {SourceDataset} from '../../trace_processor/dataset'; 23import {LONG, LONG_NULL, NUM, STR} from '../../trace_processor/query_result'; 24import {ThreadSliceDetailsPanel} from '../details/thread_slice_details_tab'; 25import {BigintMath} from '../../base/bigint_math'; 26import {clamp} from '../../base/math_utils'; 27 28export interface VisualizedArgsTrackAttrs { 29 readonly uri: string; 30 readonly trace: Trace; 31 readonly trackId: number; 32 readonly maxDepth: number; 33 readonly argName: string; 34 readonly onClose: () => void; 35} 36 37export async function createVisualizedArgsTrack({ 38 uri, 39 trace, 40 trackId, 41 maxDepth, 42 argName, 43 onClose, 44}: VisualizedArgsTrackAttrs) { 45 const uuid = uuidv4Sql(); 46 const escapedArgName = argName.replace(/[^a-zA-Z]/g, '_'); 47 const viewName = `__arg_visualisation_helper_${escapedArgName}_${uuid}_slice`; 48 49 await createView( 50 trace.engine, 51 viewName, 52 ` 53 with slice_with_arg as ( 54 select 55 slice.id, 56 slice.track_id, 57 slice.ts, 58 slice.dur, 59 slice.thread_dur, 60 NULL as cat, 61 args.display_value as name 62 from slice 63 join args using (arg_set_id) 64 where args.key='${argName}' 65 ) 66 select 67 *, 68 (select count() 69 from ancestor_slice(s1.id) s2 70 join slice_with_arg s3 on s2.id=s3.id 71 ) as depth 72 from slice_with_arg s1 73 order by id 74 `, 75 ); 76 77 return new DatasetSliceTrack({ 78 trace, 79 uri, 80 dataset: new SourceDataset({ 81 schema: { 82 id: NUM, 83 ts: LONG, 84 dur: LONG, 85 depth: NUM, 86 name: STR, 87 thread_dur: LONG_NULL, 88 }, 89 src: viewName, 90 filter: { 91 col: 'track_id', 92 eq: trackId, 93 }, 94 }), 95 initialMaxDepth: maxDepth, 96 detailsPanel: () => new ThreadSliceDetailsPanel(trace), 97 fillRatio: (row) => { 98 if (row.dur > 0n && row.thread_dur !== null) { 99 return clamp(BigintMath.ratio(row.thread_dur, row.dur), 0, 1); 100 } else { 101 return 1; 102 } 103 }, 104 shellButtons: () => { 105 return m(Button, { 106 onclick: onClose, 107 icon: Icons.Close, 108 title: 'Close all visualised args tracks for this arg', 109 compact: true, 110 }); 111 }, 112 }); 113} 114