From b7d0de8cf0d7b442d967532e376bc349555d24f6 Mon Sep 17 00:00:00 2001 From: liufei Date: Wed, 29 Nov 2023 10:59:12 +0800 Subject: [PATCH] =?UTF-8?q?binder,sched=5Fswitch,cpufreq,gpufreq=E5=9B=9B?= =?UTF-8?q?=E6=9D=A1=E6=B3=B3=E9=81=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liufei --- .../trace/component/chart/SpChartManager.ts | 6 +- .../component/chart/SpSegmentationChart.ts | 427 ++++++++++++++++++ .../trace/component/trace/base/TraceRow.ts | 75 ++- .../database/ui-worker/ProcedureWorker.ts | 4 + .../ui-worker/ProcedureWorkerFreqExtend.ts | 108 +++++ .../ui-worker/procedureWorkerBinder.ts | 105 +++++ 6 files changed, 715 insertions(+), 10 deletions(-) create mode 100644 ide/src/trace/component/chart/SpSegmentationChart.ts create mode 100644 ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts create mode 100644 ide/src/trace/database/ui-worker/procedureWorkerBinder.ts diff --git a/ide/src/trace/component/chart/SpChartManager.ts b/ide/src/trace/component/chart/SpChartManager.ts index 04bb5137..ce26806d 100644 --- a/ide/src/trace/component/chart/SpChartManager.ts +++ b/ide/src/trace/component/chart/SpChartManager.ts @@ -51,6 +51,7 @@ import { SpLogChart } from './SpLogChart.js'; import { SpHiSysEventChart } from './SpHiSysEventChart.js'; import { SpAllAppStartupsChart } from './SpAllAppStartups.js'; import {setVSyncData} from './VSync.js'; +import { SegMenTaTion } from './SpSegmentationChart.js'; export class SpChartManager { static APP_STARTUP_PID_ARR: Array = []; @@ -75,6 +76,7 @@ export class SpChartManager { public arkTsChart: SpArkTsChart; private logChart: SpLogChart; private spHiSysEvent: SpHiSysEventChart; + private SegMenTaTion:SegMenTaTion; constructor(trace: SpSystemTrace) { this.trace = trace; @@ -96,7 +98,8 @@ export class SpChartManager { this.arkTsChart = new SpArkTsChart(trace); this.logChart = new SpLogChart(trace); this.spHiSysEvent = new SpHiSysEventChart(trace); - this.SpAllAppStartupsChart = new SpAllAppStartupsChart(trace) + this.SpAllAppStartupsChart = new SpAllAppStartupsChart(trace); + this.SegMenTaTion = new SegMenTaTion(trace); } async init(progress: Function) { @@ -140,6 +143,7 @@ export class SpChartManager { await this.clockChart.init(); progress('Irq init', 84); await this.irqChart.init(); + await this.SegMenTaTion.init(); info('Cpu Freq Data initialized'); await this.virtualMemChart.init(); progress('fps', 85); diff --git a/ide/src/trace/component/chart/SpSegmentationChart.ts b/ide/src/trace/component/chart/SpSegmentationChart.ts new file mode 100644 index 00000000..be34e952 --- /dev/null +++ b/ide/src/trace/component/chart/SpSegmentationChart.ts @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { SpSystemTrace } from '../SpSystemTrace.js'; +import { ColorUtils } from '../trace/base/ColorUtils.js'; +import { TraceRow } from '../trace/base/TraceRow.js'; +import { info } from '../../../log/Log.js'; +import { renders } from '../../database/ui-worker/ProcedureWorker.js'; +import { EmptyRender } from '../../database/ui-worker/ProcedureWorkerCPU.js'; +import { FreqExtendRender, CpuFreqExtendStruct } from '../../database/ui-worker/ProcedureWorkerFreqExtend.js'; +import { BinderRender, binderStruct } from '../../database/ui-worker/procedureWorkerBinder.js'; +import { queryIrqList } from '../../database/SqlLite.js'; + +export class SegMenTaTion { + static trace: SpSystemTrace; + static jsonRow: TraceRow | undefined; + static GpuRow: TraceRow | undefined; + static binderRow: TraceRow | undefined; + static schedRow: TraceRow | undefined; + static freqInfoMapData: any = new Map(); + private rowFolder!: TraceRow; + static chartData: any; + // 数据切割联动 + static setChartData(type: string, data: any) { + let currentMaxValue = 0; + if (type === 'CPU-FREQ') { + let chartData = data.map((v: any) => { + if (v.value > currentMaxValue) { + currentMaxValue = v.value + } + return { + cpu: 0, + dur: v.dur, + value: v.value, + startNS: v.startNS, + cycle: v.cycle, + freq: v.freq + } + }) + CpuFreqExtendStruct.maxValue = currentMaxValue; + SegMenTaTion.jsonRow!.dataList = []; + SegMenTaTion.jsonRow!.dataListCache = []; + SegMenTaTion.jsonRow!.isComplete = false; + SegMenTaTion.jsonRow!.supplier = (): Promise> => + new Promise>((resolve) => resolve(chartData)); + } + else if (type === 'GPU-FREQ') { + let chartData = data.map((v: any) => { + + if (v.count > currentMaxValue) { + currentMaxValue = v.count + } + return { + cpu: 7, + dur: v.dur * 1000000, + value: v.count, + startNS: v.startNS, + cycle: v.cycle, + } + }) + CpuFreqExtendStruct.maxValue = currentMaxValue; + SegMenTaTion.GpuRow!.dataList = []; + SegMenTaTion.GpuRow!.dataListCache = []; + SegMenTaTion.GpuRow!.isComplete = false; + SegMenTaTion.GpuRow!.supplier = (): Promise> => + new Promise>((resolve) => resolve(chartData)); + } else if (type === 'SCHED-SWITCH') { + let chartData = data.map((v: any) => { + if (v.count > currentMaxValue) { + currentMaxValue = v.count + } + return { + cpu: 5, + dur: Number(v.duration) * 1000 * 1000, + value: v.count, + startNS: Number(v.cycleStartTime) * 1000 * 1000, + cycle: v.cycle, + } + }) + CpuFreqExtendStruct.maxValue = currentMaxValue; + SegMenTaTion.schedRow!.dataList = []; + SegMenTaTion.schedRow!.dataListCache = []; + SegMenTaTion.schedRow!.isComplete = false; + SegMenTaTion.schedRow!.supplier = (): Promise> => + new Promise>((resolve) => resolve(chartData)); + } else if (type === 'BINDER') { + let binderList: any = []; + let chartData: any; + data.map((v: any) => { + let listCount = 0 + v.map((t: any) => { + listCount += t.count + if (t.name === 'binder transaction') { + t.depth = t.count + } + if (t.name === 'binder transaction async') { + console.log(t, 'ttttttttt') + t.depth = t.count + ((v.filter((i: any) => { + return i.name === 'binder transaction' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder transaction' + })[0].count) : 0); + } + if (t.name === 'binder reply') { + t.depth = t.count + ((v.filter((i: any) => { + return i.name === 'binder transaction' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder transaction' + })[0].count) : 0) + ((v.filter((i: any) => { + return i.name === 'binder transaction async' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder transaction async' + })[0].count) : 0); + } + if (t.name === 'binder async rcv') { + t.depth = t.count + ((v.filter((i: any) => { + return i.name === 'binder transaction' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder transaction' + })[0].count) : 0) + ((v.filter((i: any) => { + return i.name === 'binder transaction async' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder transaction async' + })[0].count) : 0) + ((v.filter((i: any) => { + return i.name === 'binder reply' + }).length > 0) ? (v.filter((i: any) => { + return i.name === 'binder reply' + })[0].count) : 0) + } + binderList.push(t); + }); + binderStruct.maxHeight = binderStruct.maxHeight > listCount ? binderStruct.maxHeight : JSON.parse(JSON.stringify(listCount)); + listCount = 0 + }) + chartData = binderList.map((v: any) => { + return { + cpu: v.name === 'binder transaction' ? + 0 : v.name === 'binder transaction async' ? + 1 : v.name === 'binder reply' ? + 2 : 3, + startNS: v.startNS, + dur: v.dur, + name: `${v.name}`, + value: v.count, + depth: v.depth, + cycle: v.idx, + } + }) + SegMenTaTion.binderRow!.dataList = []; + SegMenTaTion.binderRow!.dataListCache = []; + SegMenTaTion.binderRow!.isComplete = false; + SegMenTaTion.binderRow!.style.height = `${binderStruct.maxHeight > 2 ? binderStruct.maxHeight * 20 + 20 : 40}px`; + SegMenTaTion.binderRow!.supplier = (): Promise> => + new Promise>((resolve) => resolve(chartData)); + } else { + return + } + SegMenTaTion.trace.refreshCanvas(true) + } + + // 悬浮联动 + static tabHover(type: String, tableIsHover: any = false, cycle: any) { + CpuFreqExtendStruct.isTabHover = tableIsHover; + if (type === 'CPU-FREQ' || type === 'GPU-FREQ' || type === 'SCHED-SWITCH') { + if (tableIsHover) { + CpuFreqExtendStruct.cycle = cycle + } else { + CpuFreqExtendStruct.cycle = -1 + CpuFreqExtendStruct.hoverCpuFreqStruct = undefined + } + } else if (type === 'BINDER') { + if (tableIsHover) { + binderStruct.hoverCycle = cycle + } else { + binderStruct.hoverCycle = -1; + } + } + SegMenTaTion.trace.refreshCanvas(true, 'flagChange') + } + + constructor(trace: SpSystemTrace) { + SegMenTaTion.trace = trace; + } + + async init() { + let irqList = await queryIrqList(); + if (irqList.length == 0) { + return; + } + else { + await this.initFolder(); + await this.initCpuFreq(); + await this.initGpuTrace(); + await this.initSchedTrace(); + await this.initBinderTrace(); + } + } + + async initFolder() { + let row = TraceRow.skeleton(); + row.setAttribute('disabled-check', ''); + row.rowId = `unkown`; + row.index = 0; + row.rowType = TraceRow.ROW_TYPE_SEGMENTATION; + row.rowParentId = ''; + row.folder = true; + row.style.height = '40px'; + row.name = `Segmentation`; + row.supplier = () => new Promise>((resolve) => resolve([])); + row.onThreadHandler = (useCache) => { + row.canvasSave(SegMenTaTion.trace.canvasPanelCtx!); + if (row.expansion) { + SegMenTaTion.trace.canvasPanelCtx?.clearRect(0, 0, row.frame.width, row.frame.height); + } else { + (renders['empty'] as EmptyRender).renderMainThread( + { + context: SegMenTaTion.trace.canvasPanelCtx, + useCache: useCache, + type: ``, + }, + row + ); + } + row.canvasRestore(SegMenTaTion.trace.canvasPanelCtx!); + }; + this.rowFolder = row; + SegMenTaTion.trace.rowsEL?.appendChild(row); + + } + + async initCpuFreq() { + // json文件泳道 + SegMenTaTion.jsonRow = TraceRow.skeleton(); + SegMenTaTion.jsonRow.rowId = `json0`; + SegMenTaTion.jsonRow.rowType = TraceRow.ROW_TYPE_CPU_COMPUTILITY; + SegMenTaTion.jsonRow.rowParentId = ''; + SegMenTaTion.jsonRow.style.height = '40px'; + SegMenTaTion.jsonRow.name = `Cpu Computility`; + SegMenTaTion.jsonRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; + SegMenTaTion.jsonRow.checkFile = 'json'; + // 拿到了用户传递的数据 + SegMenTaTion.jsonRow.onRowCheckFileChangeHandler = (e: any) => { + let chartData = JSON.parse(e); + let mapData = new Map(); + chartData.map((v: any) => { + for (let key in v.freqInfo) { + mapData.set(Number(key), v.freqInfo[key]) + } + SegMenTaTion.freqInfoMapData.set(v.cpuId, mapData) + mapData = new Map() + }) + } + SegMenTaTion.jsonRow.focusHandler = (ev) => { + SegMenTaTion.trace?.displayTip( + SegMenTaTion.jsonRow!, + CpuFreqExtendStruct.hoverCpuFreqStruct, + `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct!.value || 0)}` + ); + }; + SegMenTaTion.jsonRow.findHoverStruct = () => { + CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.jsonRow!.getHoverStruct(); + }; + SegMenTaTion.jsonRow.onThreadHandler = (useCache) => { + let context: CanvasRenderingContext2D; + if (SegMenTaTion.jsonRow!.currentContext) { + context = SegMenTaTion.jsonRow!.currentContext; + } else { + context = SegMenTaTion.jsonRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; + } + SegMenTaTion.jsonRow!.canvasSave(context); + (renders['freq-extend'] as FreqExtendRender).renderMainThread( + { + context: context, + useCache: useCache, + type: `json0`, + }, + SegMenTaTion.jsonRow! + ); + SegMenTaTion.jsonRow!.canvasRestore(context); + }; + SegMenTaTion.trace.rowsEL?.appendChild(SegMenTaTion.jsonRow); + this.rowFolder!.addChildTraceRow(SegMenTaTion.jsonRow); + } + + async initGpuTrace() { + SegMenTaTion.GpuRow = TraceRow.skeleton(); + SegMenTaTion.GpuRow.rowId = `gpurow`; + SegMenTaTion.GpuRow.rowType = TraceRow.ROW_TYPE_GPU_COMPUTILITY; + SegMenTaTion.GpuRow.rowParentId = ''; + SegMenTaTion.GpuRow.style.height = '40px'; + SegMenTaTion.GpuRow.name = `Gpu Computility`; + SegMenTaTion.GpuRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; + SegMenTaTion.GpuRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; + SegMenTaTion.GpuRow.supplier = (): Promise> => + new Promise>((resolve) => resolve([])); + SegMenTaTion.GpuRow.focusHandler = (ev) => { + SegMenTaTion.trace?.displayTip( + SegMenTaTion.GpuRow!, + CpuFreqExtendStruct.hoverCpuFreqStruct, + `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct?.value!)} Hz·ms` + ); + }; + SegMenTaTion.GpuRow.findHoverStruct = () => { + CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.GpuRow!.getHoverStruct(); + }; + SegMenTaTion.GpuRow.onThreadHandler = (useCache) => { + let context: CanvasRenderingContext2D; + if (SegMenTaTion.GpuRow!.currentContext) { + context = SegMenTaTion.GpuRow!.currentContext; + } else { + context = SegMenTaTion.GpuRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; + } + SegMenTaTion.GpuRow!.canvasSave(context); + (renders['freq-extend'] as FreqExtendRender).renderMainThread( + { + context: context, + useCache: useCache, + type: `json0`, + }, + SegMenTaTion.GpuRow! + ); + SegMenTaTion.GpuRow!.canvasRestore(context); + }; + SegMenTaTion.trace.rowsEL?.appendChild(SegMenTaTion.GpuRow); + this.rowFolder!.addChildTraceRow(SegMenTaTion.GpuRow); + } + + async initSchedTrace() { + SegMenTaTion.schedRow = TraceRow.skeleton(); + SegMenTaTion.schedRow.rowId = `sched_switch Count`; + SegMenTaTion.schedRow.rowType = TraceRow.ROW_TYPE_SCHED_SWITCH; + SegMenTaTion.schedRow.rowParentId = ''; + SegMenTaTion.schedRow.style.height = '40px'; + SegMenTaTion.schedRow.name = `Sched_switch Count`; + SegMenTaTion.schedRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; + SegMenTaTion.schedRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; + SegMenTaTion.schedRow.focusHandler = (ev) => { + SegMenTaTion.trace?.displayTip( + SegMenTaTion.schedRow!, + CpuFreqExtendStruct.hoverCpuFreqStruct, + `${ColorUtils.formatNumberComma(CpuFreqExtendStruct.hoverCpuFreqStruct?.value!)} Hz·ms` + ); + }; + SegMenTaTion.schedRow.findHoverStruct = () => { + CpuFreqExtendStruct.hoverCpuFreqStruct = SegMenTaTion.schedRow!.getHoverStruct(); + }; + SegMenTaTion.schedRow.supplier = (): Promise> => + new Promise>((resolve) => resolve([])); + SegMenTaTion.schedRow.onThreadHandler = (useCache) => { + let context: CanvasRenderingContext2D; + if (SegMenTaTion.schedRow!.currentContext) { + context = SegMenTaTion.schedRow!.currentContext; + } else { + context = SegMenTaTion.schedRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; + } + SegMenTaTion.schedRow!.canvasSave(context); + (renders['freq-extend'] as FreqExtendRender).renderMainThread( + { + context: context, + useCache: useCache, + type: `json0`, + }, + SegMenTaTion.schedRow! + ); + SegMenTaTion.schedRow!.canvasRestore(context); + }; + SegMenTaTion.trace.rowsEL?.appendChild(SegMenTaTion.schedRow); + this.rowFolder!.addChildTraceRow(SegMenTaTion.schedRow); + } + + async initBinderTrace() { + SegMenTaTion.binderRow = TraceRow.skeleton(); + SegMenTaTion.binderRow.rowId = `binderrow`; + SegMenTaTion.binderRow.rowType = TraceRow.ROW_TYPE_BINDER_COUNT; + SegMenTaTion.binderRow.rowParentId = ''; + SegMenTaTion.binderRow.name = `Binder Count`; + SegMenTaTion.binderRow.style.height = '40px'; + SegMenTaTion.binderRow.favoriteChangeHandler = SegMenTaTion.trace.favoriteChangeHandler; + SegMenTaTion.binderRow.selectChangeHandler = SegMenTaTion.trace.selectChangeHandler; + SegMenTaTion.binderRow.findHoverStruct = () => { + binderStruct.hoverCpuFreqStruct = SegMenTaTion.binderRow!.getHoverStruct(); + }; + // SegMenTaTion.binderRow.focusHandler = (ev) => { + // SegMenTaTion.trace?.displayTip( + // SegMenTaTion.binderRow!, + // binderStruct.hoverCpuFreqStruct, + // `Cycle: ${binderStruct.hoverCpuFreqStruct?.cycle}
+ // Name: ${binderStruct.hoverCpuFreqStruct?.name || ''}
+ // Count: ${binderStruct.hoverCpuFreqStruct?.value || ''}` + // ); + // }; + SegMenTaTion.binderRow.supplier = (): Promise> => + new Promise>((resolve) => resolve([])); + SegMenTaTion.binderRow.onThreadHandler = (useCache) => { + let context: CanvasRenderingContext2D; + if (SegMenTaTion.binderRow!.currentContext) { + context = SegMenTaTion.binderRow!.currentContext; + } else { + context = SegMenTaTion.binderRow!.collect ? SegMenTaTion.trace.canvasFavoritePanelCtx! : SegMenTaTion.trace.canvasPanelCtx!; + } + SegMenTaTion.binderRow!.canvasSave(context); + (renders['binder'] as BinderRender).renderMainThread( + { + context: context, + useCache: useCache, + type: `binder`, + }, + SegMenTaTion.binderRow! + ); + SegMenTaTion.binderRow!.canvasRestore(context); + }; + SegMenTaTion.trace.rowsEL?.appendChild(SegMenTaTion.binderRow); + this.rowFolder!.addChildTraceRow(SegMenTaTion.binderRow); + } +} diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index 39db22c5..07de4e95 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -44,6 +44,11 @@ let dragDirection: string = ''; @element('trace-row') export class TraceRow extends HTMLElement { + static ROW_TYPE_SEGMENTATION = 'segmentation'; + static ROW_TYPE_CPU_COMPUTILITY = 'cpu_computility'; + static ROW_TYPE_GPU_COMPUTILITY = 'gpu_computility'; + static ROW_TYPE_SCHED_SWITCH = 'sched_switch'; + static ROW_TYPE_BINDER_COUNT = 'binder'; static ROW_TYPE_CPU = 'cpu-data'; static ROW_TYPE_CPU_STATE = 'cpu-state'; static ROW_TYPE_CPU_FREQ = 'cpu-freq'; @@ -174,6 +179,9 @@ export class TraceRow extends HTMLElement { parentRowEl: TraceRow | undefined; _rowSettingList: Array | null | undefined; _docompositionList: Array | undefined; + public rowCheckFileEL: LitIcon | null | undefined; + public inputEL: any; + public onRowCheckFileChangeHandler: ((file: any) => void) | undefined | null; focusHandler?: (ev: MouseEvent) => void | undefined; findHoverStruct?: () => void | undefined; @@ -188,12 +196,12 @@ export class TraceRow extends HTMLElement { isOffScreen: boolean; skeleton?: boolean; } = { - canvasNumber: 1, - alpha: false, - contextId: '2d', - isOffScreen: true, - skeleton: false, - } + canvasNumber: 1, + alpha: false, + contextId: '2d', + isOffScreen: true, + skeleton: false, + } ) { super(); this.args = args; @@ -235,6 +243,15 @@ export class TraceRow extends HTMLElement { 'row-setting-popover-direction', ]; } + + get checkFile(): string { + return this.getAttribute('row-file') || 'disable' + } + + set checkFile(value: string) { + this.setAttribute('row-file', value) + } + get docompositionList(): Array | undefined { return this._docompositionList; } @@ -657,6 +674,8 @@ export class TraceRow extends HTMLElement { this.canvasVessel = this.shadowRoot?.querySelector('.panel-vessel'); this.tipEL = this.shadowRoot?.querySelector('.tip'); let canvasNumber = this.args['canvasNumber']; + this.rowCheckFileEL = this.shadowRoot?.querySelector('.checkfile'); + this.inputEL = this.shadowRoot?.querySelector('#fileinput'); if (!this.args['skeleton']) { for (let i = 0; i < canvasNumber; i++) { let canvas = document.createElement('canvas'); @@ -667,6 +686,24 @@ export class TraceRow extends HTMLElement { } } } + + this.rowCheckFileEL!.onclick = () => { + this.inputEL.click(); + this.inputEL.addEventListener('change', (e: any) => { + let file = e.target.files[0]; + if (file.type === 'application/json') { + let file_reader = new FileReader(); + file_reader.readAsText(file, 'UTF-8'); + file_reader.onload = () => { + let fc = file_reader.result; + this.onRowCheckFileChangeHandler?.(fc) + }; + } else { + return + } + }, false) + } + this.checkBoxEL!.onchange = (ev: any) => { info('checkBoxEL onchange '); if (!ev.target.checked) { @@ -693,7 +730,7 @@ export class TraceRow extends HTMLElement { this.checkType = '-1'; } - addRowSettingPop(): void{ + addRowSettingPop(): void { this.rowSettingPop = document.createElement('lit-popover') as LitPopover; this.rowSettingPop.innerHTML = `
@@ -722,7 +759,7 @@ export class TraceRow extends HTMLElement { this.describeEl?.appendChild(this.rowSettingPop); } - getRowSettingKeys() : Array { + getRowSettingKeys(): Array { if (this.rowSetting === 'enable') { return this.rowSettingTree!.getCheckdKeys(); } @@ -741,7 +778,7 @@ export class TraceRow extends HTMLElement { } } - enableCollapseChart() : void { + enableCollapseChart(): void { this._enableCollapseChart = true; this.nameEL!.onclick = () => { if (this.funcExpand) { @@ -1421,14 +1458,34 @@ export class TraceRow extends HTMLElement { :host([row-setting='enable']:not([check-type='-1'])) .collect{ margin-right: 5px; } + :host(:not([row-file='json'])) .checkfile{ + display:none; + } + :host(:not([row-file='json'])) input{ + display:none; + } + :host([row-file='json']) .checkfile{ + display:flex; + } + :host([row-file='json']) input{ + display:flex; + } + :host([row-file='json']) .folder{ + display:none; + } + :host([row-file="json"]) .describe:hover .checkfile{ + color:#000; + }
+
+
`; } diff --git a/ide/src/trace/database/ui-worker/ProcedureWorker.ts b/ide/src/trace/database/ui-worker/ProcedureWorker.ts index 1766c0d9..1a6bbab8 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorker.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorker.ts @@ -59,6 +59,8 @@ import { LogRender } from './ProcedureWorkerLog.js'; import { HiPerfCallChartRender } from './ProcedureWorkerHiPerfCallChart.js'; import { HiSysEventRender } from './ProcedureWorkerHiSysEvent.js'; import { AllAppStartupRender } from './ProcedureWorkerAllAppStartup.js'; +import { FreqExtendRender } from './ProcedureWorkerFreqExtend.js'; +import { BinderRender } from './procedureWorkerBinder.js'; let dataList: any = {}; let dataList2: any = {}; @@ -115,6 +117,8 @@ export let renders: any = { snapshot: new SnapshotRender(), logs: new LogRender(), hiSysEvent: new HiSysEventRender(), + 'freq-extend': new FreqExtendRender(), + 'binder' : new BinderRender() }; function match(type: string, req: RequestMessage): void { diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts new file mode 100644 index 00000000..93759b2f --- /dev/null +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFreqExtend.ts @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon.js'; +import { TraceRow } from '../../component/trace/base/TraceRow.js'; + +export class FreqExtendRender extends Render { + renderMainThread( + freqReq: { + context: CanvasRenderingContext2D; + useCache: boolean; + type: string; + }, + row: TraceRow + ) { + let freqList = row.dataList; + let freqFilter = row.dataListCache; + dataFilterHandler(freqList, freqFilter, { + startKey: 'startNS', + durKey: 'dur', + startNS: TraceRow.range?.startNS ?? 0, + endNS: TraceRow.range?.endNS ?? 0, + totalNS: TraceRow.range?.totalNS ?? 0, + frame: row.frame, + paddingTop: 5, + useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), + }); + + if (row.isHover) { + CpuFreqExtendStruct.cycle = -1; + } + freqReq.context.beginPath(); + for (let re of freqFilter) { + if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { + CpuFreqExtendStruct.hoverCpuFreqStruct = re; + } + if (!row.isHover && !CpuFreqExtendStruct.isTabHover) CpuFreqExtendStruct.hoverCpuFreqStruct = undefined; + CpuFreqExtendStruct.draw(freqReq.context, re); + } + freqReq.context.closePath(); + } +} + +export class CpuFreqExtendStruct extends BaseStruct { + static maxValue: number = 0; + static cycle: number = -1; + static isTabHover: boolean = false; + static hoverCpuFreqStruct: CpuFreqExtendStruct | undefined; + freq: number = 0; + static selectCpuFreqStruct: CpuFreqExtendStruct | undefined; + cpu: number | undefined; + value: number | undefined; + startNS: number | undefined; + dur: number | undefined; //自补充,数据库没有返回 + cycle: number | undefined; + + static draw(freqContext: CanvasRenderingContext2D, data: CpuFreqExtendStruct) { + if (data.frame) { + let width = data.frame.width || 0; + let index = data.cpu || 0; + index += 2; + freqContext.fillStyle = ColorUtils.colorForTid(index); + freqContext.strokeStyle = ColorUtils.colorForTid(index); + if (data === CpuFreqExtendStruct.hoverCpuFreqStruct + || data === CpuFreqExtendStruct.selectCpuFreqStruct + || data === CpuFreqExtendStruct.selectCpuFreqStruct + || (data.cycle === CpuFreqExtendStruct.cycle + && CpuFreqExtendStruct.cycle !== -1)) { + freqContext.fillStyle = '#ff0000'; + freqContext.strokeStyle = '#ff0000'; + freqContext.lineWidth = 3; + freqContext.globalAlpha = 0.6; + let drawHeight: number = Math.floor( + ((data.value || 0) * (data.frame.height || 0) * 1.0) / CpuFreqExtendStruct.maxValue + ); + if (drawHeight < 1) { + drawHeight = 1; + } + freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); + freqContext.globalAlpha = 0.8; + freqContext.strokeRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); + } else { + freqContext.globalAlpha = 0.6; + freqContext.lineWidth = 1; + let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0)) / CpuFreqExtendStruct.maxValue); + if (drawHeight < 1) { + drawHeight = 1; + } + freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width, drawHeight); + } + } + freqContext.globalAlpha = 1.0; + freqContext.lineWidth = 1; + } +} diff --git a/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts b/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts new file mode 100644 index 00000000..af4af2d0 --- /dev/null +++ b/ide/src/trace/database/ui-worker/procedureWorkerBinder.ts @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ColorUtils } from '../../component/trace/base/ColorUtils.js'; +import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon.js'; +import { TraceRow } from '../../component/trace/base/TraceRow.js'; +import { drawString, Rect } from './ProcedureWorkerCommon.js'; + +export class BinderRender extends Render { + renderMainThread( + freqReq: { + context: CanvasRenderingContext2D; + useCache: boolean; + type: string; + }, + row: TraceRow + ) { + let freqList = row.dataList; + let freqFilter = row.dataListCache; + dataFilterHandler(freqList, freqFilter, { + startKey: 'startNS', + durKey: 'dur', + startNS: TraceRow.range?.startNS ?? 0, + endNS: TraceRow.range?.endNS ?? 0, + totalNS: TraceRow.range?.totalNS ?? 0, + frame: row.frame, + paddingTop: 5, + useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), + }); + freqReq.context.beginPath(); + for (let re of freqFilter) { + if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { + binderStruct.hoverCpuFreqStruct = re; + } + if (!row.isHover) { + binderStruct.hoverCpuFreqStruct = undefined; + } + binderStruct.draw(freqReq.context, re); + } + freqReq.context.closePath(); + } +} +export class binderStruct extends BaseStruct { + static hoverCpuFreqStruct: binderStruct | undefined; + static selectCpuFreqStruct: binderStruct | undefined; + static maxHeight: number = 0; + static hoverCycle: number = -1; + cpu: number | undefined; + value: number = 0; + cycle: number = 0; + startNS: number | undefined; + dur: number | undefined; //自补充,数据库没有返回 + name: string | undefined; + depth: number = 0; + static draw(freqContext: CanvasRenderingContext2D, data: binderStruct) { + if (data.frame) { + let index = data.cpu || 0; + let color = ''; + if (data.name === 'binder transaction') { + color = '#e86b6a'; + } + if (data.name === 'binder transaction async') { + color = '#36baa4'; + } + if (data.name === 'binder reply') { + color = '#8770d3'; + } + if (data.name === 'binder async rcv') { + color = '#0cbdd4'; + } + freqContext.fillStyle = color + if (data === binderStruct.hoverCpuFreqStruct || data === binderStruct.selectCpuFreqStruct || data.cycle === binderStruct.hoverCycle) { + freqContext.globalAlpha = 1; + freqContext.lineWidth = 1; + freqContext.fillRect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20); + } else { + freqContext.globalAlpha = 0.6; + freqContext.lineWidth = 1; + freqContext.fillRect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20); + } + if (data.frame.width > 8) { + freqContext.lineWidth = 1; + freqContext.fillStyle = ColorUtils.funcTextColor( + ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.name || '', 0, ColorUtils.FUNC_COLOR.length)] + ); + freqContext.textBaseline = 'middle'; + drawString(freqContext, `${data.name || ''}`, 6, new Rect(data.frame.x, binderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20), data); + } + freqContext.globalAlpha = 1.0; + freqContext.lineWidth = 1; + } + } +} \ No newline at end of file -- Gitee