diff --git a/ide/src/trace/component/SpSystemTrace.ts b/ide/src/trace/component/SpSystemTrace.ts index 2dac160969e56676cdf9f06d7d2389f800a36155..f177d95d1d9e0b6753f1381bf15bd65d9bf470b3 100644 --- a/ide/src/trace/component/SpSystemTrace.ts +++ b/ide/src/trace/component/SpSystemTrace.ts @@ -23,7 +23,16 @@ import { querySceneSearchFunc, querySearchFunc, threadPool, + queryProcessMemData, + queryProcess, + queryProcessByTable, + queryProcessThreads, + queryProcessThreadsByTable, + getFunDataByTid, + queryProcessMem, } from '../database/SqlLite.js'; +import { MemRender,ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem.js'; +import { renders } from '../database/ui-worker/ProcedureWorker.js'; import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js'; import { TimerShaftElement } from './trace/TimerShaftElement.js'; import './trace/base/TraceSheet.js'; @@ -45,6 +54,7 @@ import { drawWakeUp, drawWakeUpList, isFrameContainPoint, + drawVsync, LineType, ns2x, ns2xByTimeShaft, @@ -57,7 +67,7 @@ import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js'; import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js'; import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js'; import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread.js'; -import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js'; +import { func, FuncStruct,FuncRender } from '../database/ui-worker/ProcedureWorkerFunc.js'; import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState.js'; import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU.js'; import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess.js'; @@ -194,7 +204,15 @@ export class SpSystemTrace extends BaseElement { private expandRowList: Array> = []; private _slicesList: Array = []; private _flagList: Array = []; - + private _frameList: Array = []; + private _isVsync: boolean = false; + private processes: Array =[]; + private processFromTable: Array =[]; + private queryProcessThreadResult: Array=[]; + private queryProcessThreadsByTableResult: Array=[]; + private queryFunData: Array =[]; + private querydbData : Array=[]; + private dbProcessMen: Array=[]; set snapshotFile(data: FileInfo) { this.snapshotFiles = data; } @@ -223,6 +241,164 @@ export class SpSystemTrace extends BaseElement { this.linkNodes.push([startPoint, endPoint]); } + async makeVsyncLine(){ + if(this._isVsync){ + let vsyncPid: number = 0;//单框架进程Id + let vsyncUPid: number = 0;//单框架 + let vsyncTid: number = 0;//单框架 + let vsyncDbPid : number = 0;//双框架进程Id + let context = this.canvasPanelCtx!; + this.processes = this.processes.length>0? this.processes:await queryProcess(); + this.processFromTable = this.processFromTable.length>0?this.processFromTable:await queryProcessByTable(); + this.queryProcessThreadResult = this.queryProcessThreadResult.length>0?this.queryProcessThreadResult:await queryProcessThreads(); + this.queryProcessThreadsByTableResult = this.queryProcessThreadsByTableResult.length>0?this.queryProcessThreadsByTableResult:await queryProcessThreadsByTable(); + let processList = Utils.removeDuplicates(this.processes,this.processFromTable,'pid'); + info('ProcessList Data size is: ', processList!.length); + let processThreads = Utils.removeDuplicates(this.queryProcessThreadResult,this.queryProcessThreadsByTableResult,'tid'); + info('The amount of initialized process threads data is : ', processThreads!.length); + processList.forEach((ele:any)=>{ + if(ele.processName === 'render_service'){//单框架 + vsyncPid = Number(`${ele.pid}`) + }else if(ele.processName === 'surfaceflinger'){ + vsyncDbPid = Number(`${ele.pid}`) + } + }) + if(vsyncPid){ + let vsyncThreads = processThreads.filter((thread:any)=>thread.pid == vsyncPid && thread.tid !=0); + vsyncThreads.forEach((ele:any)=>{ + if(ele.threadName == 'VSyncGenerator'){ + vsyncTid = Number(`${ele.tid}`); + vsyncUPid = Number(`${ele.upid}`); + } + }) + let funcRow = TraceRow.skeleton(); + this.queryFunData = this.queryFunData.length>0?this.queryFunData:await getFunDataByTid(vsyncTid || 0,vsyncUPid || 0); + if(this.queryFunData.length >0){ + for(let i =0;i { + return ( + data.funName != null && + (data.funName.toLowerCase().startsWith('binder transaction async') || //binder transaction + data.funName.toLowerCase().startsWith('binder async') || + data.funName.toLowerCase().startsWith('binder reply')) + ); + }; + this.queryFunData.forEach((fun) => { + if (isBinder(fun)) { + } else { + if (fun.dur === -1) { + fun.dur = (TraceRow.range?.totalNS || 0) - (fun.startTs || 0); + fun.flag = 'Did not end'; + } + } + }); + funcRow.dataList = []; + funcRow.dataList.push(...this.queryFunData); + (renders.func as FuncRender).renderMainThread( + { + context:context, + useCache:false, + type:`fun${vsyncTid}VSyncGenerator` + }, + funcRow + ); + if(funcRow.dataListCache.length > 0){ + let drawVsData = []; + let dataStart:any={}; + let dataEnd: any={}; + let drawLineList = []; + if(funcRow.dataListCache[0]!.color! == '#fff'){ + dataStart = { + color: '#808080', + frame:{ + x:0,y:0,width:1,height:20 + } + } + }else{ + dataStart = { + color: '#fff', + frame:{ + x:0,y:0,width:1,height:20 + } + } + } + if(funcRow.dataListCache[funcRow.dataListCache.length-1]!.color! == '#fff'){ + dataEnd = { + color: '#808080', + frame:{ + x:this.canvasPanel!.clientWidth,y:0,width:1,height:20 + } + } + }else{ + dataEnd = { + color: '#fff', + frame:{ + x:this.canvasPanel!.clientWidth,y:0,width:1,height:20 + } + } + } + drawVsData.push(dataStart); + drawVsData.push(...funcRow.dataListCache); + drawVsData.push(dataEnd); + for(let i = 0;i(); + this.dbProcessMen = this.dbProcessMen.length>0?this.dbProcessMen:await queryProcessMem(); + let vsyncDbThreads = this.dbProcessMen.filter((thread:any)=> thread.pid == vsyncDbPid && thread.tid != 0); + vsyncDbThreads.forEach(async(ele:any)=>{ + if(ele.trackName == 'VSYNC-app'){ + this.querydbData = this.querydbData.length>0?this.querydbData:await queryProcessMemData(ele.trackId); + dbRow.dataList = []; + dbRow.dataList.push(...this.querydbData); + let context = this.canvasPanelCtx!; + (renders['mem'] as MemRender).renderMainThread( + { + context:context, + useCache:false, + type:`mem ${ele.trackId} VSYNC-app` + }, + dbRow + ); + let value_1_list = []; + let value_0_list = []; + let drawList = []; + this._frameList = []; + for(let i =0; i 0){ + for(let i =0; i < this._frameList.length; i++){ + if(this._frameList[i].frame){ + drawVsync( + this.canvasPanelCtx, + TraceRow.range!.startNS, + TraceRow.range!.endNS, + TraceRow.range!.totalNS, + { + x:this._frameList[i].frame!.x!, + y:this._frameList[i].frame!.y!, + width:this._frameList[i].frame!.width!, + height:this.canvasPanel!.clientHeight! + } as Rect, + this._frameList[i]!.color! + ); + } + } + } + +//---------------------------新增代码结束-------------------------- + // Draw the connection curve if (this.linkNodes) { drawLinkLines( @@ -1775,6 +1979,11 @@ export class SpSystemTrace extends BaseElement { this.mouseCurrentPosition = 0; this.isMouseLeftDown = false; this.style.cursor = 'default'; + requestAnimationFrame(()=>{ + setTimeout(()=>{ + this.makeVsyncLine(); + },100) + }) return; } TraceRow.isUserInteraction = false; @@ -1853,6 +2062,11 @@ export class SpSystemTrace extends BaseElement { if (keyPressWASD) { this.keyPressMap.set(keyPress, true); this.hoverFlag = null; + requestAnimationFrame(()=>{ + setTimeout(()=>{ + this.makeVsyncLine(); + },100) + }) } this.timerShaftEL!.documentOnKeyPress(ev, this.currentSlicesTime); if (keyPress === 'f') { @@ -1988,8 +2202,22 @@ export class SpSystemTrace extends BaseElement { documentOnKeyUp = (ev: KeyboardEvent) => { if (!this.loadTraceCompleted) return; let keyPress = ev.key.toLocaleLowerCase(); + if(keyPress === 'v'){ + this._isVsync = !this._isVsync; + if(this._isVsync){ + this.makeVsyncLine(); + }else{ + this.refreshCanvas(true,'',[]) + } + + } if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { this.keyPressMap.set(keyPress, false); + requestAnimationFrame(()=>{ + setTimeout(()=>{ + this.makeVsyncLine(); + },100) + }) } TraceRow.isUserInteraction = false; this.observerScrollHeightEnable = false; @@ -3543,6 +3771,11 @@ export class SpSystemTrace extends BaseElement { (e) => { if (e.ctrlKey) { if (e.deltaY > 0) { + requestAnimationFrame(()=>{ + setTimeout(()=>{ + this.makeVsyncLine(); + },100) + }) e.preventDefault(); e.stopPropagation(); let eventS = new KeyboardEvent('keypress', { @@ -3556,6 +3789,11 @@ export class SpSystemTrace extends BaseElement { }, 200); } if (e.deltaY < 0) { + requestAnimationFrame(()=>{ + setTimeout(()=>{ + this.makeVsyncLine(); + },100) + }) e.preventDefault(); e.stopPropagation(); let eventW = new KeyboardEvent('keypress', { @@ -4218,6 +4456,15 @@ export class SpSystemTrace extends BaseElement { } init = async (param: { buf?: ArrayBuffer; url?: string }, wasmConfigUri: string, progress: Function) => { + this._frameList = []; + this.processes = []; + this.processFromTable = []; + this.queryProcessThreadResult = []; + this.queryProcessThreadsByTableResult = []; + this.queryFunData = []; + this.dbProcessMen = []; + this.querydbData = []; + this._isVsync = false; progress('Load database', 6); this.rowsPaneEL!.scroll({ top: 0, diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts index 7b70000303e87bbf5f894c8312050fdc8f91dc3d..eb98cb7a368daaef00dc63f0697529c9d4d8b210 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerCommon.ts @@ -737,6 +737,26 @@ export function drawSelectionRange(context: any, params: TraceRow) { } } +//---------------------------新增代码开始-------------------------- + +export function drawVsync( + vsyncContext: CanvasRenderingContext2D | any, + startNS: number, + endNS: number, + totalNS: number, + frame:Rect, + color:string +){ + vsyncContext.lineWidth = 2; + vsyncContext.fillStyle = color?color:"#808080"; + vsyncContext.globalAlpha = 0.4; + vsyncContext.fillRect(frame.x,frame.y,frame.width,frame.height); + // vsyncContext.stroke(); + // vsyncContext.closePath(); +} + +//---------------------------新增代码结束-------------------------- + export function drawWakeUp( wakeUpContext: CanvasRenderingContext2D | any, wake: WakeupBean | undefined | null, diff --git a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts index 363d3c87f6c83b3fc9bd7640a9d78f874fc904fe..502f39b8dd070ea845b42ad386919d9f7e17e5de 100644 --- a/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts +++ b/ide/src/trace/database/ui-worker/ProcedureWorkerFunc.ts @@ -116,6 +116,7 @@ export function func( } export class FuncStruct extends BaseFuncStruct { + [x: string]: any; static hoverFuncStruct: FuncStruct | undefined; static selectFuncStruct: FuncStruct | undefined; flag: string | undefined; // 570000