1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace'; 17fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow'; 18fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker'; 19fb726d48Sopenharmony_ciimport { info } from '../../../log/Log'; 20fb726d48Sopenharmony_ciimport { ClockRender, ClockStruct } from '../../database/ui-worker/ProcedureWorkerClock'; 21fb726d48Sopenharmony_ciimport { ColorUtils } from '../trace/base/ColorUtils'; 22fb726d48Sopenharmony_ciimport { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 23fb726d48Sopenharmony_ciimport { Utils } from '../trace/base/Utils'; 24fb726d48Sopenharmony_ciimport { clockDataSender } from '../../database/data-trafic/ClockDataSender'; 25fb726d48Sopenharmony_ciimport { queryClockData } from '../../database/sql/Clock.sql'; 26fb726d48Sopenharmony_ciimport { DmaFenceRender, DmaFenceStruct } from '../../database/ui-worker/ProcedureWorkerDmaFence'; 27fb726d48Sopenharmony_ciimport { dmaFenceSender } from '../../database/data-trafic/dmaFenceSender'; 28fb726d48Sopenharmony_ciimport { queryDmaFenceName } from '../../database/sql/dmaFence.sql'; 29fb726d48Sopenharmony_ciimport { BaseStruct } from '../../bean/BaseStruct'; 30fb726d48Sopenharmony_ciimport { promises } from 'dns'; 31fb726d48Sopenharmony_ci 32fb726d48Sopenharmony_ciexport class SpClockChart { 33fb726d48Sopenharmony_ci private readonly trace: SpSystemTrace; 34fb726d48Sopenharmony_ci 35fb726d48Sopenharmony_ci constructor(trace: SpSystemTrace) { 36fb726d48Sopenharmony_ci this.trace = trace; 37fb726d48Sopenharmony_ci } 38fb726d48Sopenharmony_ci 39fb726d48Sopenharmony_ci async init(parentRow?: TraceRow<BaseStruct>, traceId?: string): Promise<void> { 40fb726d48Sopenharmony_ci let clockList = await queryClockData(traceId); 41fb726d48Sopenharmony_ci if (clockList.length === 0) { 42fb726d48Sopenharmony_ci return; 43fb726d48Sopenharmony_ci } 44fb726d48Sopenharmony_ci let folder = await this.initFolder(traceId); 45fb726d48Sopenharmony_ci if (parentRow) { 46fb726d48Sopenharmony_ci parentRow.addChildTraceRow(folder); 47fb726d48Sopenharmony_ci } else { 48fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folder); 49fb726d48Sopenharmony_ci } 50fb726d48Sopenharmony_ci await this.initData(folder, clockList, traceId); 51fb726d48Sopenharmony_ci await this.initDmaFence(folder); 52fb726d48Sopenharmony_ci } 53fb726d48Sopenharmony_ci 54fb726d48Sopenharmony_ci private clockSupplierFrame( 55fb726d48Sopenharmony_ci traceRow: TraceRow<ClockStruct>, 56fb726d48Sopenharmony_ci it: { 57fb726d48Sopenharmony_ci name: string; 58fb726d48Sopenharmony_ci num: number; 59fb726d48Sopenharmony_ci srcname: string; 60fb726d48Sopenharmony_ci maxValue?: number; 61fb726d48Sopenharmony_ci }, 62fb726d48Sopenharmony_ci isState: boolean, 63fb726d48Sopenharmony_ci isScreenState: boolean, 64fb726d48Sopenharmony_ci ): void { 65fb726d48Sopenharmony_ci traceRow.supplierFrame = (): Promise<ClockStruct[]> => { 66fb726d48Sopenharmony_ci let promiseData = null; 67fb726d48Sopenharmony_ci if (it.name.endsWith(' Frequency')) { 68fb726d48Sopenharmony_ci promiseData = clockDataSender(it.srcname, 'clockFrequency', traceRow); 69fb726d48Sopenharmony_ci } else if (isState) { 70fb726d48Sopenharmony_ci promiseData = clockDataSender(it.srcname, 'clockState', traceRow); 71fb726d48Sopenharmony_ci } else if (isScreenState) { 72fb726d48Sopenharmony_ci promiseData = clockDataSender('', 'screenState', traceRow); 73fb726d48Sopenharmony_ci } 74fb726d48Sopenharmony_ci if (promiseData === null) { 75fb726d48Sopenharmony_ci // @ts-ignore 76fb726d48Sopenharmony_ci return new Promise<Array<unknown>>((resolve) => resolve([])); 77fb726d48Sopenharmony_ci } else { 78fb726d48Sopenharmony_ci // @ts-ignore 79fb726d48Sopenharmony_ci return promiseData.then((resultClock: Array<unknown>) => { 80fb726d48Sopenharmony_ci for (let j = 0; j < resultClock.length; j++) { 81fb726d48Sopenharmony_ci // @ts-ignore 82fb726d48Sopenharmony_ci resultClock[j].type = 'measure'; // @ts-ignore 83fb726d48Sopenharmony_ci if ((resultClock[j].value || 0) > it.maxValue!) { 84fb726d48Sopenharmony_ci // @ts-ignore 85fb726d48Sopenharmony_ci it.maxValue = resultClock[j].value || 0; 86fb726d48Sopenharmony_ci } 87fb726d48Sopenharmony_ci if (j > 0) { 88fb726d48Sopenharmony_ci // @ts-ignore 89fb726d48Sopenharmony_ci resultClock[j].delta = (resultClock[j].value || 0) - (resultClock[j - 1].value || 0); 90fb726d48Sopenharmony_ci } else { 91fb726d48Sopenharmony_ci // @ts-ignore 92fb726d48Sopenharmony_ci resultClock[j].delta = 0; 93fb726d48Sopenharmony_ci } 94fb726d48Sopenharmony_ci } 95fb726d48Sopenharmony_ci return resultClock; 96fb726d48Sopenharmony_ci }); 97fb726d48Sopenharmony_ci } 98fb726d48Sopenharmony_ci }; 99fb726d48Sopenharmony_ci } 100fb726d48Sopenharmony_ci 101fb726d48Sopenharmony_ci private clockThreadHandler( 102fb726d48Sopenharmony_ci traceRow: TraceRow<ClockStruct>, 103fb726d48Sopenharmony_ci it: { 104fb726d48Sopenharmony_ci name: string; 105fb726d48Sopenharmony_ci num: number; 106fb726d48Sopenharmony_ci srcname: string; 107fb726d48Sopenharmony_ci maxValue?: number; 108fb726d48Sopenharmony_ci }, 109fb726d48Sopenharmony_ci isState: boolean, 110fb726d48Sopenharmony_ci isScreenState: boolean, 111fb726d48Sopenharmony_ci clockId: number 112fb726d48Sopenharmony_ci ): void { 113fb726d48Sopenharmony_ci traceRow.onThreadHandler = (useCache): void => { 114fb726d48Sopenharmony_ci let context: CanvasRenderingContext2D; 115fb726d48Sopenharmony_ci if (traceRow.currentContext) { 116fb726d48Sopenharmony_ci context = traceRow.currentContext; 117fb726d48Sopenharmony_ci } else { 118fb726d48Sopenharmony_ci context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 119fb726d48Sopenharmony_ci } 120fb726d48Sopenharmony_ci traceRow.canvasSave(context); 121fb726d48Sopenharmony_ci (renders.clock as ClockRender).renderMainThread( 122fb726d48Sopenharmony_ci { 123fb726d48Sopenharmony_ci context: context, 124fb726d48Sopenharmony_ci useCache: useCache, 125fb726d48Sopenharmony_ci type: it.name, 126fb726d48Sopenharmony_ci maxValue: it.maxValue === 0 ? 1 : it.maxValue!, 127fb726d48Sopenharmony_ci index: clockId, 128fb726d48Sopenharmony_ci maxName: 129fb726d48Sopenharmony_ci isState || isScreenState 130fb726d48Sopenharmony_ci ? it.maxValue!.toString() 131fb726d48Sopenharmony_ci : Utils.getFrequencyWithUnit(it.maxValue! / 1000).maxFreqName, 132fb726d48Sopenharmony_ci }, 133fb726d48Sopenharmony_ci traceRow 134fb726d48Sopenharmony_ci ); 135fb726d48Sopenharmony_ci traceRow.canvasRestore(context, this.trace); 136fb726d48Sopenharmony_ci }; 137fb726d48Sopenharmony_ci } 138fb726d48Sopenharmony_ci 139fb726d48Sopenharmony_ci async initData(folder: TraceRow<BaseStruct>, clockList: Array<{ 140fb726d48Sopenharmony_ci name: string; 141fb726d48Sopenharmony_ci num: number; 142fb726d48Sopenharmony_ci srcname: string; 143fb726d48Sopenharmony_ci maxValue?: number; 144fb726d48Sopenharmony_ci }>, traceId?: string): Promise<void> { 145fb726d48Sopenharmony_ci let clockStartTime = new Date().getTime(); 146fb726d48Sopenharmony_ci info('clockList data size is: ', clockList!.length); 147fb726d48Sopenharmony_ci if (!traceId) { 148fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(folder); 149fb726d48Sopenharmony_ci } 150fb726d48Sopenharmony_ci ClockStruct.maxValue = clockList.map((item) => item.num).reduce((a, b) => Math.max(a, b)); 151fb726d48Sopenharmony_ci for (let i = 0; i < clockList.length; i++) { 152fb726d48Sopenharmony_ci const it = clockList[i]; 153fb726d48Sopenharmony_ci it.maxValue = 0; 154fb726d48Sopenharmony_ci let traceRow = TraceRow.skeleton<ClockStruct>(traceId); 155fb726d48Sopenharmony_ci let isState = it.name.endsWith(' State'); 156fb726d48Sopenharmony_ci let isScreenState = it.name.endsWith('ScreenState'); 157fb726d48Sopenharmony_ci traceRow.rowId = it.name; 158fb726d48Sopenharmony_ci traceRow.rowType = TraceRow.ROW_TYPE_CLOCK; 159fb726d48Sopenharmony_ci traceRow.rowParentId = folder.rowId; 160fb726d48Sopenharmony_ci traceRow.style.height = '40px'; 161fb726d48Sopenharmony_ci traceRow.name = it.name; 162fb726d48Sopenharmony_ci traceRow.rowHidden = !folder.expansion; 163fb726d48Sopenharmony_ci traceRow.setAttribute('children', ''); 164fb726d48Sopenharmony_ci traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 165fb726d48Sopenharmony_ci traceRow.selectChangeHandler = this.trace.selectChangeHandler; 166fb726d48Sopenharmony_ci this.clockSupplierFrame(traceRow, it, isState, isScreenState); 167fb726d48Sopenharmony_ci traceRow.getCacheData = (args: unknown): Promise<ClockStruct[]> | undefined => { 168fb726d48Sopenharmony_ci let result: Promise<ClockStruct[]> | undefined; 169fb726d48Sopenharmony_ci if (it.name.endsWith(' Frequency')) { 170fb726d48Sopenharmony_ci result = clockDataSender(it.srcname, 'clockFrequency', traceRow, args); 171fb726d48Sopenharmony_ci } else if (isState) { 172fb726d48Sopenharmony_ci result = clockDataSender(it.srcname, 'clockState', traceRow, args); 173fb726d48Sopenharmony_ci } else if (isScreenState) { 174fb726d48Sopenharmony_ci result = clockDataSender('', 'screenState', traceRow, args); 175fb726d48Sopenharmony_ci } 176fb726d48Sopenharmony_ci return result; 177fb726d48Sopenharmony_ci }; 178fb726d48Sopenharmony_ci traceRow.focusHandler = (ev): void => { 179fb726d48Sopenharmony_ci this.trace?.displayTip( 180fb726d48Sopenharmony_ci traceRow, 181fb726d48Sopenharmony_ci ClockStruct.hoverClockStruct, 182fb726d48Sopenharmony_ci `<span>${ColorUtils.formatNumberComma(ClockStruct.hoverClockStruct?.value!)}</span>` 183fb726d48Sopenharmony_ci ); 184fb726d48Sopenharmony_ci }; 185fb726d48Sopenharmony_ci traceRow.findHoverStruct = (): void => { 186fb726d48Sopenharmony_ci ClockStruct.hoverClockStruct = traceRow.getHoverStruct(); 187fb726d48Sopenharmony_ci }; 188fb726d48Sopenharmony_ci this.clockThreadHandler(traceRow, it, isState, isScreenState, i); 189fb726d48Sopenharmony_ci folder.addChildTraceRow(traceRow); 190fb726d48Sopenharmony_ci } 191fb726d48Sopenharmony_ci let durTime = new Date().getTime() - clockStartTime; 192fb726d48Sopenharmony_ci info('The time to load the ClockData is: ', durTime); 193fb726d48Sopenharmony_ci } 194fb726d48Sopenharmony_ci 195fb726d48Sopenharmony_ci // @ts-ignore 196fb726d48Sopenharmony_ci async initDmaFence(folder: TraceRow<unknown>): Promise<void> { 197fb726d48Sopenharmony_ci let dmaFenceNameList = await queryDmaFenceName(); 198fb726d48Sopenharmony_ci if (dmaFenceNameList.length) { 199fb726d48Sopenharmony_ci let dmaFenceList = []; 200fb726d48Sopenharmony_ci const timelineValues = dmaFenceNameList.map(obj => obj.timeline); 201fb726d48Sopenharmony_ci for (let i = 0; i < timelineValues.length; i++) { 202fb726d48Sopenharmony_ci let traceRow: TraceRow<DmaFenceStruct> = TraceRow.skeleton<DmaFenceStruct>(); 203fb726d48Sopenharmony_ci traceRow.rowId = timelineValues[i]; 204fb726d48Sopenharmony_ci traceRow.rowType = TraceRow.ROW_TYPE_DMA_FENCE; 205fb726d48Sopenharmony_ci traceRow.rowParentId = folder.rowId; 206fb726d48Sopenharmony_ci traceRow.style.height = 40 + 'px'; 207fb726d48Sopenharmony_ci traceRow.name = `${timelineValues[i]}`; 208fb726d48Sopenharmony_ci traceRow.folder = false; 209fb726d48Sopenharmony_ci traceRow.rowHidden = !folder.expansion; 210fb726d48Sopenharmony_ci traceRow.setAttribute('children', ''); 211fb726d48Sopenharmony_ci traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 212fb726d48Sopenharmony_ci traceRow.selectChangeHandler = this.trace.selectChangeHandler; 213fb726d48Sopenharmony_ci // @ts-ignore 214fb726d48Sopenharmony_ci traceRow.supplierFrame = (): Promise<DmaFenceStruct[]> => { 215fb726d48Sopenharmony_ci return dmaFenceSender('dma_fence_init', `${timelineValues[i]}`, traceRow).then((res) => { 216fb726d48Sopenharmony_ci res.forEach((item: unknown) => { 217fb726d48Sopenharmony_ci // @ts-ignore 218fb726d48Sopenharmony_ci let detail = Utils.DMAFENCECAT_MAP.get(item.id!); 219fb726d48Sopenharmony_ci if (detail) { 220fb726d48Sopenharmony_ci let catValue = (detail.cat.match(/^dma_(.*)$/))![1]; 221fb726d48Sopenharmony_ci // @ts-ignore 222fb726d48Sopenharmony_ci item.sliceName = catValue.endsWith('ed') ? `${catValue.slice(0, -2)}(${detail.seqno})` : `${catValue}(${detail.seqno})`; 223fb726d48Sopenharmony_ci // @ts-ignore 224fb726d48Sopenharmony_ci item.driver = detail.driver; 225fb726d48Sopenharmony_ci // @ts-ignore 226fb726d48Sopenharmony_ci item.context = detail.context; 227fb726d48Sopenharmony_ci // @ts-ignore 228fb726d48Sopenharmony_ci item.depth = 0; 229fb726d48Sopenharmony_ci } 230fb726d48Sopenharmony_ci 231fb726d48Sopenharmony_ci }); 232fb726d48Sopenharmony_ci return dmaFenceList = res; 233fb726d48Sopenharmony_ci }); 234fb726d48Sopenharmony_ci 235fb726d48Sopenharmony_ci }; 236fb726d48Sopenharmony_ci traceRow.onThreadHandler = (useCache): void => { 237fb726d48Sopenharmony_ci let context: CanvasRenderingContext2D; 238fb726d48Sopenharmony_ci if (traceRow.currentContext) { 239fb726d48Sopenharmony_ci context = traceRow.currentContext; 240fb726d48Sopenharmony_ci } else { 241fb726d48Sopenharmony_ci context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 242fb726d48Sopenharmony_ci } 243fb726d48Sopenharmony_ci traceRow.canvasSave(context); 244fb726d48Sopenharmony_ci (renders.dmaFence as DmaFenceRender).renderMainThread( 245fb726d48Sopenharmony_ci { 246fb726d48Sopenharmony_ci dmaFenceContext: context, 247fb726d48Sopenharmony_ci useCache: useCache, 248fb726d48Sopenharmony_ci type: 'dmaFence', 249fb726d48Sopenharmony_ci maxValue: 20, 250fb726d48Sopenharmony_ci index: 1, 251fb726d48Sopenharmony_ci maxName: '' 252fb726d48Sopenharmony_ci }, 253fb726d48Sopenharmony_ci traceRow 254fb726d48Sopenharmony_ci ); 255fb726d48Sopenharmony_ci traceRow.canvasRestore(context, this.trace); 256fb726d48Sopenharmony_ci }; 257fb726d48Sopenharmony_ci folder.addChildTraceRow(traceRow); 258fb726d48Sopenharmony_ci } 259fb726d48Sopenharmony_ci 260fb726d48Sopenharmony_ci } 261fb726d48Sopenharmony_ci 262fb726d48Sopenharmony_ci } 263fb726d48Sopenharmony_ci 264fb726d48Sopenharmony_ci 265fb726d48Sopenharmony_ci async initFolder(traceId?: string): Promise<TraceRow<BaseStruct>> { 266fb726d48Sopenharmony_ci let clockFolder = TraceRow.skeleton(traceId); 267fb726d48Sopenharmony_ci clockFolder.rowId = 'Clocks'; 268fb726d48Sopenharmony_ci clockFolder.index = 0; 269fb726d48Sopenharmony_ci clockFolder.rowType = TraceRow.ROW_TYPE_CLOCK_GROUP; 270fb726d48Sopenharmony_ci clockFolder.rowParentId = ''; 271fb726d48Sopenharmony_ci clockFolder.style.height = '40px'; 272fb726d48Sopenharmony_ci clockFolder.folder = true; 273fb726d48Sopenharmony_ci clockFolder.name = 'Clocks'; 274fb726d48Sopenharmony_ci clockFolder.favoriteChangeHandler = this.trace.favoriteChangeHandler; 275fb726d48Sopenharmony_ci clockFolder.selectChangeHandler = this.trace.selectChangeHandler; 276fb726d48Sopenharmony_ci clockFolder.supplier = (): Promise<BaseStruct[]> => new Promise<Array<BaseStruct>>((resolve) => resolve([])); 277fb726d48Sopenharmony_ci clockFolder.onThreadHandler = (useCache): void => { 278fb726d48Sopenharmony_ci clockFolder.canvasSave(this.trace.canvasPanelCtx!); 279fb726d48Sopenharmony_ci if (clockFolder.expansion) { 280fb726d48Sopenharmony_ci this.trace.canvasPanelCtx?.clearRect(0, 0, clockFolder.frame.width, clockFolder.frame.height); 281fb726d48Sopenharmony_ci } else { 282fb726d48Sopenharmony_ci (renders.empty as EmptyRender).renderMainThread( 283fb726d48Sopenharmony_ci { 284fb726d48Sopenharmony_ci context: this.trace.canvasPanelCtx, 285fb726d48Sopenharmony_ci useCache: useCache, 286fb726d48Sopenharmony_ci type: '', 287fb726d48Sopenharmony_ci }, 288fb726d48Sopenharmony_ci clockFolder 289fb726d48Sopenharmony_ci ); 290fb726d48Sopenharmony_ci } 291fb726d48Sopenharmony_ci clockFolder.canvasRestore(this.trace.canvasPanelCtx!, this.trace); 292fb726d48Sopenharmony_ci }; 293fb726d48Sopenharmony_ci return clockFolder; 294fb726d48Sopenharmony_ci } 295fb726d48Sopenharmony_ci} 296