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 {HSLColor} from '../../base/color'; 16import {makeColorScheme} from '../../components/colorizer'; 17import {ColorScheme} from '../../base/color_scheme'; 18import {LONG, NUM, STR, STR_NULL} from '../../trace_processor/query_result'; 19import {Trace} from '../../public/trace'; 20import {SourceDataset} from '../../trace_processor/dataset'; 21import {DatasetSliceTrack} from '../../components/tracks/dataset_slice_track'; 22import {ThreadSliceDetailsPanel} from '../../components/details/thread_slice_details_tab'; 23 24// color named and defined based on Material Design color palettes 25// 500 colors indicate a timeline slice is not a partial jank (not a jank or 26// full jank) 27const BLUE_500 = makeColorScheme(new HSLColor('#03A9F4')); 28const BLUE_200 = makeColorScheme(new HSLColor('#90CAF9')); 29const GREEN_500 = makeColorScheme(new HSLColor('#4CAF50')); 30const GREEN_200 = makeColorScheme(new HSLColor('#A5D6A7')); 31const YELLOW_500 = makeColorScheme(new HSLColor('#FFEB3B')); 32const YELLOW_100 = makeColorScheme(new HSLColor('#FFF9C4')); 33const RED_500 = makeColorScheme(new HSLColor('#FF5722')); 34const RED_200 = makeColorScheme(new HSLColor('#EF9A9A')); 35const LIGHT_GREEN_500 = makeColorScheme(new HSLColor('#C0D588')); 36const LIGHT_GREEN_100 = makeColorScheme(new HSLColor('#DCEDC8')); 37const PINK_500 = makeColorScheme(new HSLColor('#F515E0')); 38const PINK_200 = makeColorScheme(new HSLColor('#F48FB1')); 39 40export function createActualFramesTrack( 41 trace: Trace, 42 uri: string, 43 maxDepth: number, 44 trackIds: ReadonlyArray<number>, 45) { 46 return new DatasetSliceTrack({ 47 trace, 48 uri, 49 dataset: new SourceDataset({ 50 src: 'actual_frame_timeline_slice', 51 schema: { 52 id: NUM, 53 name: STR, 54 ts: LONG, 55 dur: LONG, 56 jank_type: STR, 57 jank_tag: STR_NULL, 58 jank_severity_type: STR_NULL, 59 }, 60 filter: { 61 col: 'track_id', 62 in: trackIds, 63 }, 64 }), 65 colorizer: (row) => { 66 return getColorSchemeForJank(row.jank_tag, row.jank_severity_type); 67 }, 68 initialMaxDepth: maxDepth, 69 rootTableName: 'slice', 70 detailsPanel: () => new ThreadSliceDetailsPanel(trace), 71 }); 72} 73 74function getColorSchemeForJank( 75 jankTag: string | null, 76 jankSeverityType: string | null, 77): ColorScheme { 78 if (jankSeverityType === 'Partial') { 79 switch (jankTag) { 80 case 'Self Jank': 81 return RED_200; 82 case 'Other Jank': 83 return YELLOW_100; 84 case 'Dropped Frame': 85 return BLUE_200; 86 case 'Buffer Stuffing': 87 case 'SurfaceFlinger Stuffing': 88 return LIGHT_GREEN_100; 89 case 'No Jank': // should not happen 90 return GREEN_200; 91 default: 92 return PINK_200; 93 } 94 } else { 95 switch (jankTag) { 96 case 'Self Jank': 97 return RED_500; 98 case 'Other Jank': 99 return YELLOW_500; 100 case 'Dropped Frame': 101 return BLUE_500; 102 case 'Buffer Stuffing': 103 case 'SurfaceFlinger Stuffing': 104 return LIGHT_GREEN_500; 105 case 'No Jank': 106 return GREEN_500; 107 default: 108 return PINK_500; 109 } 110 } 111} 112