1// Copyright (C) 2018 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 {colorForTid} from '../../common/colorizer'; 16import {checkerboardExcept} from '../../frontend/checkerboard'; 17import {globals} from '../../frontend/globals'; 18import {NewTrackArgs, Track} from '../../frontend/track'; 19import {trackRegistry} from '../../frontend/track_registry'; 20 21import { 22 Config, 23 Data, 24 PROCESS_SUMMARY_TRACK, 25} from './common'; 26 27const MARGIN_TOP = 5; 28const RECT_HEIGHT = 30; 29const TRACK_HEIGHT = MARGIN_TOP * 2 + RECT_HEIGHT; 30const SUMMARY_HEIGHT = TRACK_HEIGHT - MARGIN_TOP; 31 32class ProcessSummaryTrack extends Track<Config, Data> { 33 static readonly kind = PROCESS_SUMMARY_TRACK; 34 static create(args: NewTrackArgs): ProcessSummaryTrack { 35 return new ProcessSummaryTrack(args); 36 } 37 38 constructor(args: NewTrackArgs) { 39 super(args); 40 } 41 42 getHeight(): number { 43 return TRACK_HEIGHT; 44 } 45 46 renderCanvas(ctx: CanvasRenderingContext2D): void { 47 const {timeScale, visibleWindowTime} = globals.frontendLocalState; 48 const data = this.data(); 49 if (data === undefined) return; // Can't possibly draw anything. 50 51 checkerboardExcept( 52 ctx, 53 this.getHeight(), 54 timeScale.timeToPx(visibleWindowTime.start), 55 timeScale.timeToPx(visibleWindowTime.end), 56 timeScale.timeToPx(data.start), 57 timeScale.timeToPx(data.end)); 58 59 this.renderSummary(ctx, data); 60 } 61 62 // TODO(dproy): Dedup with CPU slices. 63 renderSummary(ctx: CanvasRenderingContext2D, data: Data): void { 64 const {timeScale, visibleWindowTime} = globals.frontendLocalState; 65 const startPx = Math.floor(timeScale.timeToPx(visibleWindowTime.start)); 66 const bottomY = TRACK_HEIGHT; 67 68 let lastX = startPx; 69 let lastY = bottomY; 70 71 // TODO(hjd): Dedupe this math. 72 const color = colorForTid(this.config.pidForColor); 73 color.l = Math.min(color.l + 10, 60); 74 color.s -= 20; 75 76 ctx.fillStyle = `hsl(${color.h}, ${color.s}%, ${color.l}%)`; 77 ctx.beginPath(); 78 ctx.moveTo(lastX, lastY); 79 for (let i = 0; i < data.utilizations.length; i++) { 80 // TODO(dproy): Investigate why utilization is > 1 sometimes. 81 const utilization = Math.min(data.utilizations[i], 1); 82 const startTime = i * data.bucketSizeSeconds + data.start; 83 84 lastX = Math.floor(timeScale.timeToPx(startTime)); 85 86 ctx.lineTo(lastX, lastY); 87 lastY = MARGIN_TOP + Math.round(SUMMARY_HEIGHT * (1 - utilization)); 88 ctx.lineTo(lastX, lastY); 89 } 90 ctx.lineTo(lastX, bottomY); 91 ctx.closePath(); 92 ctx.fill(); 93 } 94} 95 96trackRegistry.register(ProcessSummaryTrack); 97