1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 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 */ 15 16import { SpSystemTrace } from '../SpSystemTrace'; 17import { TraceRow } from '../trace/base/TraceRow'; 18import { renders } from '../../database/ui-worker/ProcedureWorker'; 19import { info } from '../../../log/Log'; 20import { PerfToolRender, PerfToolStruct } from '../../database/ui-worker/ProcedureWorkerPerfTool'; 21import { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 22import { queryPerfOutputData, queryPerfToolsDur } from '../../database/sql/SqlLite.sql'; 23 24export class SpPerfOutputDataChart { 25 private trace: SpSystemTrace; 26 private startTime: number | undefined; 27 private perfOutputArr: Array<string> | undefined; 28 private dur: number | undefined; 29 30 constructor(trace: SpSystemTrace) { 31 this.trace = trace; 32 } 33 34 async init(): Promise<void> { 35 let perfOutputData = await queryPerfOutputData(); 36 if (perfOutputData.length === 0) { 37 return; 38 } 39 let perfToolsDur = await queryPerfToolsDur(); 40 if (perfToolsDur.length > 0) { 41 // @ts-ignore 42 this.dur = perfToolsDur[0].dur; 43 } else { 44 this.dur = 3000000000; 45 } 46 // @ts-ignore 47 this.perfOutputArr = perfOutputData[0].name.split(':')[2].split(','); 48 // @ts-ignore 49 let endTime: number = perfOutputData[0].ts; 50 this.startTime = endTime - window.recordStartNS - this.dur!; 51 if (this.startTime < 0) { 52 this.startTime = 0; 53 } 54 let folder = await this.initFolder(); 55 this.trace.rowsEL?.appendChild(folder); 56 this.initData(folder); 57 } 58 59 private clockThreadHandler( 60 traceRow: TraceRow<PerfToolStruct>, 61 it: { 62 name: string; 63 }, 64 perfId: number 65 ): void { 66 traceRow.onThreadHandler = (useCache): void => { 67 let context: CanvasRenderingContext2D; 68 if (traceRow.currentContext) { 69 context = traceRow.currentContext; 70 } else { 71 context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 72 } 73 traceRow.canvasSave(context); 74 (renders.perfTool as PerfToolRender).renderMainThread( 75 { 76 context: context, 77 useCache: useCache, 78 type: it.name, 79 index: perfId, 80 }, 81 traceRow 82 ); 83 traceRow.canvasRestore(context, this.trace); 84 }; 85 } 86 87 // @ts-ignore 88 async initData(folder: TraceRow<unknown>): Promise<void> { 89 let perfToolStartTime = new Date().getTime(); 90 let perfToolList = [ 91 { name: 'Application Process CPU Power Consumption(MAS)', idx: 27 }, 92 { name: 'RS Process CPU Power Consumption(MAS)', idx: 28 }, 93 { name: 'Media Process CPU Power Consumption(MAS)', idx: 29 }, 94 { name: 'Foundation Process CPU Power Consumption(MAS)', idx: 30 }, 95 { name: 'Gpu Power Consumption(MAS)', idx: 31 }, 96 { name: 'DDR Power Consumption(MAS)', idx: 32 }, 97 { name: 'IO Count', idx: 35 }, 98 { name: 'Block Count', idx: 36 }, 99 { name: 'IPI Count(Application Main Thread)', idx: 51 }, 100 { name: 'IPI Count(RS)', idx: 52 }, 101 ]; 102 info('perfTools data size is: ', perfToolList!.length); 103 for (let i = 0; i < perfToolList.length; i++) { 104 const it = perfToolList[i]; 105 let traceRow = TraceRow.skeleton<PerfToolStruct>(); 106 traceRow.rowId = i + ''; 107 traceRow.rowType = TraceRow.ROW_TYPE_PERF_TOOL; 108 traceRow.rowParentId = folder.rowId; 109 traceRow.style.height = '40px'; 110 traceRow.name = it.name; 111 traceRow.rowHidden = !folder.expansion; 112 traceRow.setAttribute('children', ''); 113 traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 114 traceRow.selectChangeHandler = this.trace.selectChangeHandler; 115 traceRow.supplierFrame = (): Promise<PerfToolStruct[]> => { 116 let data = new PerfToolStruct(); 117 data.startNS = this.startTime; 118 data.dur = this.dur; 119 data.count = this.perfOutputArr![it.idx]; 120 data.id = i + 1; 121 data.name = it.name; 122 // @ts-ignore 123 return new Promise<Array<unknown>>((resolve) => resolve([data])); 124 }; 125 traceRow.findHoverStruct = (): void => { 126 PerfToolStruct.hoverPerfToolStruct = traceRow.getHoverStruct(); 127 }; 128 this.clockThreadHandler(traceRow, it, i); 129 folder.addChildTraceRow(traceRow); 130 } 131 let durTime = new Date().getTime() - perfToolStartTime; 132 info('The time to load the ClockData is: ', durTime); 133 } 134 135 // @ts-ignore 136 async initFolder(): Promise<TraceRow<unknown>> { 137 let perfFolder = TraceRow.skeleton(); 138 perfFolder.rowId = 'perfTool'; 139 perfFolder.index = 0; 140 perfFolder.rowType = TraceRow.ROW_TYPE_PERF_TOOL_GROUP; 141 perfFolder.rowParentId = ''; 142 perfFolder.style.height = '40px'; 143 perfFolder.folder = true; 144 perfFolder.name = 'Perf Tools'; 145 perfFolder.favoriteChangeHandler = this.trace.favoriteChangeHandler; 146 perfFolder.selectChangeHandler = this.trace.selectChangeHandler; 147 // @ts-ignore 148 perfFolder.supplier = (): Promise<unknown[]> => new Promise<Array<unknown>>((resolve) => resolve([])); 149 perfFolder.onThreadHandler = (useCache): void => { 150 perfFolder.canvasSave(this.trace.canvasPanelCtx!); 151 if (perfFolder.expansion) { 152 this.trace.canvasPanelCtx?.clearRect(0, 0, perfFolder.frame.width, perfFolder.frame.height); 153 } else { 154 (renders.empty as EmptyRender).renderMainThread( 155 { 156 context: this.trace.canvasPanelCtx, 157 useCache: useCache, 158 type: '', 159 }, 160 perfFolder 161 ); 162 } 163 perfFolder.canvasRestore(this.trace.canvasPanelCtx!, this.trace); 164 }; 165 return perfFolder; 166 } 167} 168