1// Copyright (C) 2021 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 {ColumnDef} from '../../common/aggregation_data'; 16import {Area, Sorting} from '../../common/state'; 17import {ACTUAL_FRAMES_SLICE_TRACK_KIND} from '../../core/track_kinds'; 18import {globals} from '../../frontend/globals'; 19import {Engine} from '../../trace_processor/engine'; 20 21import {AggregationController} from './aggregation_controller'; 22 23export class FrameAggregationController extends AggregationController { 24 async createAggregateView(engine: Engine, area: Area) { 25 await engine.query(`drop view if exists ${this.kind};`); 26 27 const selectedSqlTrackIds: number[] = []; 28 for (const trackKey of area.tracks) { 29 const track = globals.state.tracks[trackKey]; 30 // Track will be undefined for track groups. 31 if (track?.uri !== undefined) { 32 const trackInfo = globals.trackManager.resolveTrackInfo(track.uri); 33 if (trackInfo?.kind === ACTUAL_FRAMES_SLICE_TRACK_KIND) { 34 trackInfo.trackIds && selectedSqlTrackIds.push(...trackInfo.trackIds); 35 } 36 } 37 } 38 if (selectedSqlTrackIds.length === 0) return false; 39 40 const query = `create view ${this.kind} as 41 SELECT 42 jank_type, 43 count(1) as occurrences, 44 MIN(dur) as minDur, 45 AVG(dur) as meanDur, 46 MAX(dur) as maxDur 47 FROM actual_frame_timeline_slice 48 WHERE track_id IN (${selectedSqlTrackIds}) AND 49 ts + dur > ${area.start} AND 50 ts < ${area.end} group by jank_type`; 51 52 await engine.query(query); 53 return true; 54 } 55 56 getTabName() { 57 return 'Frames'; 58 } 59 60 async getExtra() {} 61 62 getDefaultSorting(): Sorting { 63 return {column: 'occurrences', direction: 'DESC'}; 64 } 65 66 getColumnDefinitions(): ColumnDef[] { 67 return [ 68 { 69 title: 'Jank Type', 70 kind: 'STRING', 71 columnConstructor: Uint16Array, 72 columnId: 'jank_type', 73 }, 74 { 75 title: 'Min duration', 76 kind: 'NUMBER', 77 columnConstructor: Uint16Array, 78 columnId: 'minDur', 79 }, 80 { 81 title: 'Max duration', 82 kind: 'NUMBER', 83 columnConstructor: Uint16Array, 84 columnId: 'maxDur', 85 }, 86 { 87 title: 'Mean duration', 88 kind: 'NUMBER', 89 columnConstructor: Uint16Array, 90 columnId: 'meanDur', 91 }, 92 { 93 title: 'Occurrences', 94 kind: 'NUMBER', 95 columnConstructor: Uint16Array, 96 columnId: 'occurrences', 97 sum: true, 98 }, 99 ]; 100 } 101} 102