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 { ThreadStruct, ThreadStructOnClick } from '../database/ui-worker/ProcedureWorkerThread'; 18import { TraceRow } from './trace/base/TraceRow'; 19import { JankStruct, JankStructOnClick } from '../database/ui-worker/ProcedureWorkerJank'; 20import { HeapSnapshotStruct, HeapSnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerHeapSnapshot'; 21import { FuncStruct, funcStructOnClick } from '../database/ui-worker/ProcedureWorkerFunc'; 22import { CpuFreqStruct, CpuFreqStructOnClick } from '../database/ui-worker/ProcedureWorkerFreq'; 23import { ClockStruct, ClockStructOnClick } from '../database/ui-worker/ProcedureWorkerClock'; 24import { DmaFenceStruct, DmaFenceStructOnClick } from '../database/ui-worker/ProcedureWorkerDmaFence'; 25import { SnapshotStruct, SnapshotStructOnClick } from '../database/ui-worker/ProcedureWorkerSnapshot'; 26import { IrqStruct, IrqStructOnClick } from '../database/ui-worker/ProcedureWorkerIrq'; 27import { HeapStruct, HeapStructOnClick } from '../database/ui-worker/ProcedureWorkerHeap'; 28import { JsCpuProfilerStruct, JsCpuProfilerStructOnClick } from '../database/ui-worker/ProcedureWorkerCpuProfiler'; 29import { AppStartupStruct, AppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAppStartup'; 30import { AllAppStartupStruct, allAppStartupStructOnClick } from '../database/ui-worker/ProcedureWorkerAllAppStartup'; 31import { SoStruct, SoStructOnClick } from '../database/ui-worker/ProcedureWorkerSoInit'; 32import { FrameAnimationStruct, FrameAnimationStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameAnimation'; 33import { FrameDynamicStruct, FrameDynamicStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameDynamic'; 34import { FrameSpacingStruct, FrameSpacingStructOnClick } from '../database/ui-worker/ProcedureWorkerFrameSpacing'; 35import { SampleStruct, sampleStructOnClick } from '../database/ui-worker/ProcedureWorkerBpftrace'; 36import { SportRuler } from './trace/timer-shaft/SportRuler'; 37import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; 38import { LitSearch } from './trace/search/Search'; 39import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent'; 40import type { SpKeyboard } from './SpKeyboard'; 41import { enableVSync } from './chart/VSync'; 42import { CpuStruct, CpuStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCPU'; 43import { ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem'; 44import { CpuStateStruct, CpuStateStructOnClick } from '../database/ui-worker/cpu/ProcedureWorkerCpuState'; 45import { 46 CpuFreqLimitsStruct, 47 CpuFreqLimitsStructOnClick 48} from '../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits'; 49import { FlagsConfig } from './SpFlags'; 50import { LitMainMenu } from '../../base-ui/menu/LitMainMenu'; 51import { PerfToolsStructOnClick, PerfToolStruct } from '../database/ui-worker/ProcedureWorkerPerfTool'; 52import { Utils } from './trace/base/Utils'; 53import { BaseStruct } from '../bean/BaseStruct'; 54import { GpuCounterStruct, gpuCounterStructOnClick } from '../database/ui-worker/ProcedureWorkerGpuCounter'; 55import { HangStructOnClick } from '../database/ui-worker/ProcedureWorkerHang'; 56import { XpowerStruct, XpowerStructOnClick } from '../database/ui-worker/ProcedureWorkerXpower'; 57import { SpAiAnalysisPage } from './SpAiAnalysisPage'; 58 59function timeoutJudge(sp: SpSystemTrace): number { 60 let timeoutJudge = window.setTimeout((): void => { 61 if (SpSystemTrace.wakeupList.length && CpuStruct.selectCpuStruct) { 62 let checkHandlerKey: boolean = true; 63 let saveSelectCpuStruct: unknown = JSON.parse(sessionStorage.getItem('saveselectcpustruct')!); 64 for (const item of SpSystemTrace.wakeupList) { 65 if (item.ts === CpuStruct.selectCpuStruct.startTime && item.dur === CpuStruct.selectCpuStruct.dur) { 66 checkHandlerKey = false; 67 if (SpSystemTrace.wakeupList[0].schedulingDesc) { 68 //@ts-ignore 69 SpSystemTrace.wakeupList.unshift(saveSelectCpuStruct); 70 } 71 sp.refreshCanvas(true); 72 break; 73 } else if ( 74 //@ts-ignore 75 saveSelectCpuStruct.startTime === CpuStruct.selectCpuStruct.startTime && 76 //@ts-ignore 77 saveSelectCpuStruct.dur === CpuStruct.selectCpuStruct.dur 78 ) { 79 // 如果点击的是第一层,保持唤醒树不变 80 checkHandlerKey = false; 81 sp.refreshCanvas(true); 82 break; 83 } 84 } 85 // 点击线程在唤醒树内 86 if (!checkHandlerKey) { 87 // 查询获取tab表格数据 88 window.publish(window.SmartEvent.UI.WakeupList, SpSystemTrace.wakeupList); 89 } else { 90 // 不在唤醒树内,清空数组 91 sp.wakeupListNull(); 92 sp.refreshCanvas(true); 93 } 94 } else { 95 sp.wakeupListNull(); 96 sp.refreshCanvas(true); 97 } 98 clearTimeout(timeoutJudge); 99 }, 10); 100 return timeoutJudge; 101} 102 103function threadClickHandlerFunc(sp: SpSystemTrace): (e: ThreadStruct) => void { 104 let threadClickHandler = (d: ThreadStruct): void => { 105 sp.observerScrollHeightEnable = false; 106 sp.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true); 107 let cpuRow = sp.queryAllTraceRow<TraceRow<CpuStruct>>( 108 `trace-row[row-id='${Utils.getDistributedRowId(d.cpu)}'][row-type='cpu-data']`, 109 (row) => row.rowId === `${Utils.getDistributedRowId(d.cpu)}` && row.rowType === 'cpu-data' 110 )[0]; 111 if (cpuRow) { 112 sp.currentRow = cpuRow; 113 cpuRow.fixedList = [ 114 { 115 startTime: d.startTime, 116 dur: d.dur, 117 tid: d.tid, 118 id: d.id, 119 processId: d.pid, 120 cpu: d.cpu, 121 argSetID: d.argSetID, 122 }, 123 ]; 124 let findEntry = cpuRow!.fixedList[0]; 125 sp.rechargeCpuData( 126 // @ts-ignore 127 findEntry, // @ts-ignore 128 cpuRow.dataListCache.find((it) => it.startTime > findEntry.startTime) 129 ); 130 if ( 131 // @ts-ignore 132 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || // @ts-ignore 133 findEntry!.startTime! > TraceRow.range!.endNS 134 ) { 135 sp.timerShaftEL?.setRangeNS( 136 // @ts-ignore 137 findEntry!.startTime! - findEntry!.dur! * 2, // @ts-ignore 138 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 139 ); 140 } 141 sp.hoverStructNull().selectStructNull().wakeupListNull(); // @ts-ignore 142 CpuStruct.hoverCpuStruct = findEntry; // @ts-ignore 143 CpuStruct.selectCpuStruct = findEntry; // @ts-ignore 144 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 145 sp.traceSheetEL?.displayCpuData( 146 CpuStruct.selectCpuStruct!, 147 (wakeUpBean) => { 148 sp.removeLinkLinesByBusinessType('thread'); 149 CpuStruct.wakeupBean = wakeUpBean; 150 sp.refreshCanvas(true); 151 }, 152 cpuClickHandlerFunc(sp) 153 ); 154 } 155 }; 156 return threadClickHandler; 157} 158 159//点击prio箭头刷新canvas 160function prioClickHandlerFunc(sp: SpSystemTrace): (d: unknown) => void { 161 return function (d: unknown): void { 162 // @ts-ignore 163 ThreadStruct.prioCount = d; 164 ThreadStruct.isClickPrio = true; 165 sp.refreshCanvas(true); 166 }; 167} 168 169function scrollToFuncHandlerFunc(sp: SpSystemTrace): Function { 170 let funClickHandle = (funcStruct: unknown): void => { 171 // @ts-ignore 172 if (funcStruct.chainId) { 173 } 174 sp.observerScrollHeightEnable = true; 175 // @ts-ignore 176 sp.moveRangeToCenter(funcStruct.startTs!, funcStruct.dur!); 177 sp.scrollToActFunc(funcStruct, false); 178 }; 179 return funClickHandle; 180} 181 182function scrollToFunc(sp: SpSystemTrace): Function { 183 let funClickHandle = (funcStruct: unknown): void => { 184 // @ts-ignore 185 if (funcStruct.chainId) { 186 } 187 sp.observerScrollHeightEnable = true; 188 // @ts-ignore 189 sp.scrollToActFunc(funcStruct, false); 190 }; 191 return funClickHandle; 192} 193 194function jankClickHandlerFunc(sp: SpSystemTrace): Function { 195 let jankClickHandler = (d: unknown): void => { 196 sp.observerScrollHeightEnable = true; 197 let jankRowParent: unknown; 198 //@ts-ignore 199 if (d.rowId === 'actual frameTime') { 200 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>("trace-row[row-id='frameTime']"); 201 } else { 202 jankRowParent = sp.shadowRoot?.querySelector<TraceRow<JankStruct>>( 203 //@ts-ignore 204 `trace-row[row-type='process'][row-id='${d.pid}']` 205 ); 206 } 207 //@ts-ignore 208 jankRowParent!.expansion = true; 209 let jankRow: unknown; 210 //@ts-ignore 211 jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => { 212 //@ts-ignore 213 if (`${item.rowId}` === `${d.rowId}` && `${item.rowType}` === 'janks') { 214 jankRow = item; 215 } 216 }); 217 //@ts-ignore 218 sp.currentRow = jankRow; 219 if (jankRow) { 220 JankStruct.selectJankStructList.length = 0; 221 //@ts-ignore 222 let findJankEntry = jankRow!.dataListCache!.find( 223 //@ts-ignore 224 (dat: unknown) => `${dat.name}` === `${d.name}` && `${dat.pid}` === `${d.pid}` 225 ); 226 if (findJankEntry) { 227 if ( 228 findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS || 229 findJankEntry!.ts! > TraceRow.range!.endNS 230 ) { 231 sp.timerShaftEL?.setRangeNS( 232 findJankEntry!.ts! - findJankEntry!.dur! * 2, 233 findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2 234 ); 235 } 236 sp.hoverStructNull().selectStructNull().wakeupListNull(); 237 JankStruct.hoverJankStruct = findJankEntry; 238 JankStruct.selectJankStruct = findJankEntry; 239 sp.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted'); 240 sp.traceSheetEL?.displayJankData( 241 JankStruct.selectJankStruct!, 242 (datas) => { 243 sp.removeLinkLinesByBusinessType('janks'); 244 // 绘制跟自己关联的线 245 datas.forEach((data) => { 246 //@ts-ignore 247 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<BaseStruct>>( // @ts-ignore 248 `trace-row[row-type='process'][row-id='${data.pid}'][folder]` 249 ); 250 sp.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data, true); 251 }); 252 }, 253 jankClickHandler 254 ); 255 } 256 //@ts-ignore 257 sp.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true); 258 } 259 }; 260 return jankClickHandler; 261} 262 263function snapshotClickHandlerFunc(sp: SpSystemTrace): Function { 264 let snapshotClickHandler = (d: HeapSnapshotStruct): void => { 265 sp.observerScrollHeightEnable = true; 266 let snapshotRow = sp.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(`trace-row[row-id='heapsnapshot']`); 267 let task = (): void => { 268 if (snapshotRow) { 269 let findEntry = snapshotRow!.dataListCache!.find((dat) => dat.startTs === d.startTs); 270 sp.hoverStructNull(); 271 sp.selectStructNull(); 272 sp.wakeupListNull(); 273 HeapSnapshotStruct.hoverSnapshotStruct = findEntry; 274 HeapSnapshotStruct.selectSnapshotStruct = findEntry; 275 } 276 }; 277 if (snapshotRow) { 278 if (snapshotRow!.isComplete) { 279 task(); 280 } else { 281 snapshotRow!.onComplete = task; 282 } 283 } 284 }; 285 return snapshotClickHandler; 286} 287 288//@ts-ignore 289function cpuClickHandlerTask(threadRow: TraceRow<unknown>, sp: SpSystemTrace, d: CpuStruct): void { 290 if (threadRow) { 291 let findEntry = threadRow!.fixedList[0]; 292 if ( 293 //@ts-ignore 294 findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS || 295 //@ts-ignore 296 findEntry!.startTime! > TraceRow.range!.endNS 297 ) { 298 sp.timerShaftEL?.setRangeNS( 299 //@ts-ignore 300 findEntry!.startTime! - findEntry!.dur! * 2, 301 //@ts-ignore 302 findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2 303 ); 304 } 305 ThreadStruct.firstselectThreadStruct = ThreadStruct.selectThreadStruct; 306 sp.hoverStructNull().selectStructNull().wakeupListNull(); 307 //@ts-ignore 308 ThreadStruct.hoverThreadStruct = findEntry; 309 //@ts-ignore 310 ThreadStruct.selectThreadStruct = findEntry; 311 //@ts-ignore 312 sp.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted'); 313 sp.traceSheetEL?.displayThreadData( 314 ThreadStruct.selectThreadStruct!, 315 threadClickHandlerFunc(sp), // @ts-ignore 316 cpuClickHandlerFunc(sp), 317 prioClickHandlerFunc(sp), 318 (datas, str): void => { 319 sp.removeLinkLinesByBusinessType('thread'); 320 if (str === 'wakeup tid') { 321 datas.forEach((data) => { 322 //@ts-ignore 323 let endParentRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( //@ts-ignore 324 `trace-row[row-id='${data.pid}'][folder]` 325 ); 326 sp.drawThreadLine(endParentRow, ThreadStruct.firstselectThreadStruct, data); 327 }); 328 } 329 sp.refreshCanvas(true); 330 } 331 ); 332 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 333 } 334} 335 336function cpuClickHandlerFunc(sp: SpSystemTrace) { 337 return function (d: CpuStruct): void { 338 //@ts-ignore 339 let traceRow = sp.shadowRoot?.querySelector<TraceRow<unknown>>( 340 `trace-row[row-id='${Utils.getDistributedRowId(d.processId)}'][row-type='process']` 341 ); 342 if (traceRow) { 343 traceRow.expansion = true; 344 } 345 sp.observerScrollHeightEnable = true; 346 let threadRow = sp.queryAllTraceRow<TraceRow<ThreadStruct>>( 347 `trace-row[row-id='${Utils.getDistributedRowId(d.tid)}'][row-type='thread']`, 348 (row) => row.rowId === `${d.tid}` && row.rowType === 'thread' 349 )[0]; 350 sp.currentRow = threadRow; 351 if (threadRow) { 352 threadRow.fixedList = [ 353 { 354 startTime: d.startTime, 355 dur: d.dur, 356 cpu: d.cpu, 357 id: d.id, 358 tid: d.tid, 359 state: d.state, 360 pid: d.processId, 361 argSetID: d.argSetID, 362 }, 363 ]; 364 if (threadRow!.isComplete) { 365 cpuClickHandlerTask(threadRow, sp, d); 366 } else { 367 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false); 368 sp.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true); 369 threadRow!.onComplete = (): void => cpuClickHandlerTask(threadRow, sp, d); 370 } 371 } 372 }; 373} 374 375 376function allStructOnClick(clickRowType: string, sp: SpSystemTrace, row?: TraceRow<BaseStruct>, entry?: unknown): void { 377 CpuStructOnClick(clickRowType, sp, cpuClickHandlerFunc(sp), entry as CpuStruct) 378 .then(() => ThreadStructOnClick(clickRowType, sp, threadClickHandlerFunc(sp), cpuClickHandlerFunc(sp), 379 prioClickHandlerFunc(sp), entry as ThreadStruct)) 380 .then(() => funcStructOnClick(clickRowType, sp, row as TraceRow<FuncStruct>, 381 scrollToFuncHandlerFunc(sp), entry as FuncStruct)) 382 .then(() => CpuFreqStructOnClick(clickRowType, sp, entry as CpuFreqStruct)) 383 .then(() => CpuStateStructOnClick(clickRowType, sp, entry as CpuStateStruct)) 384 .then(() => CpuFreqLimitsStructOnClick(clickRowType, sp, entry as CpuFreqLimitsStruct)) 385 .then(() => ClockStructOnClick(clickRowType, sp, entry as ClockStruct)) 386 .then(() => XpowerStructOnClick(clickRowType, sp, entry as XpowerStruct)) 387 .then(() => HangStructOnClick(clickRowType, sp, scrollToFunc(sp))) 388 .then(() => DmaFenceStructOnClick(clickRowType, sp, entry as DmaFenceStruct)) 389 .then(() => SnapshotStructOnClick(clickRowType, sp, row as TraceRow<SnapshotStruct>, entry as SnapshotStruct)) 390 .then(() => IrqStructOnClick(clickRowType, sp, entry as IrqStruct)) 391 .then(() => HeapStructOnClick(clickRowType, sp, row as TraceRow<HeapStruct>, entry as HeapStruct)) 392 .then(() => JankStructOnClick(clickRowType, sp, row as TraceRow<JankStruct>, 393 jankClickHandlerFunc(sp), entry as JankStruct)) 394 .then(() => HeapSnapshotStructOnClick(clickRowType, sp, row as TraceRow<HeapSnapshotStruct>, 395 snapshotClickHandlerFunc(sp), entry as HeapSnapshotStruct)) 396 .then(() => JsCpuProfilerStructOnClick(clickRowType, sp, row as TraceRow<JsCpuProfilerStruct>, 397 entry as JsCpuProfilerStruct)) 398 .then(() => AppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AppStartupStruct)) 399 .then(() => allAppStartupStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as AllAppStartupStruct)) 400 .then(() => SoStructOnClick(clickRowType, sp, scrollToFuncHandlerFunc(sp), entry as SoStruct)) 401 .then(() => FrameAnimationStructOnClick(clickRowType, sp, 402 scrollToFuncHandlerFunc(sp), row as TraceRow<FrameAnimationStruct>, entry as FrameAnimationStruct)) 403 .then(() => FrameDynamicStructOnClick(clickRowType, sp, row, entry as FrameDynamicStruct)) 404 .then(() => FrameSpacingStructOnClick(clickRowType, sp, row!, entry as FrameSpacingStruct)) 405 .then(() => sampleStructOnClick(clickRowType, sp, row as TraceRow<SampleStruct>, entry as SampleStruct)) 406 .then(() => gpuCounterStructOnClick(clickRowType, sp, entry as GpuCounterStruct)) 407 .then(() => PerfToolsStructOnClick(clickRowType, sp, entry as PerfToolStruct)) 408 .then(() => { 409 if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) { 410 sp.removeLinkLinesByBusinessType('janks'); 411 } 412 sp.observerScrollHeightEnable = false; 413 sp.selectFlag = null; 414 sp.timerShaftEL?.removeTriangle('inverted'); 415 if (!SportRuler.isMouseInSportRuler) { 416 sp.traceSheetEL?.setMode('hidden'); 417 sp.refreshCanvas(true, 'click'); 418 } 419 }) 420 .catch((e): void => { }); 421 // @ts-ignore 422 SpAiAnalysisPage.selectChangeListener(entry.startTime || entry.startTs, (entry.startTime! || entry.startTs) + entry.dur) 423} 424export default function spSystemTraceOnClickHandler( 425 sp: SpSystemTrace, 426 clickRowType: string, 427 row?: TraceRow<BaseStruct>, 428 entry?: unknown 429): void { 430 if (row) { 431 sp.currentRow = row; 432 sp.setAttribute('clickRow', clickRowType); 433 sp.setAttribute('rowName', row.name!); 434 sp.setAttribute('rowId', row.rowId!); 435 } 436 if (!sp.loadTraceCompleted) { 437 return; 438 } 439 sp.queryAllTraceRow().forEach((it): boolean => (it.rangeSelect = false)); 440 sp.selectStructNull(); 441 sp._slicesList.forEach((slice: { selected: boolean }): void => { 442 slice.selected = false; 443 }); 444 // 判断点击的线程是否在唤醒树内 445 timeoutJudge(sp); 446 allStructOnClick(clickRowType, sp, row, entry); 447 if (!JankStruct.selectJankStruct) { 448 sp.removeLinkLinesByBusinessType('janks'); 449 } 450 if (!ThreadStruct.selectThreadStruct) { 451 sp.removeLinkLinesByBusinessType('thread'); 452 } 453 if (!FuncStruct.selectFuncStruct) { 454 sp.removeLinkLinesByBusinessType('distributed', 'func'); 455 } 456 if (row) { 457 let pointEvent = sp.createPointEvent(row); 458 SpStatisticsHttpUtil.addOrdinaryVisitAction({ 459 action: 'trace_row', // @ts-ignore 460 event: pointEvent, 461 }); 462 } 463} 464 465//@ts-ignore 466function handleActions(sp: SpSystemTrace, rows: Array<TraceRow<unknown>>, ev: MouseEvent): void { 467 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 468 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 469 if (downRow && downRow.traceId !== Utils.currentSelectTrace) { 470 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 471 return; 472 } 473 } 474 sp.rangeSelect.mouseMove(rows, ev); 475 if (sp.rangeSelect.rangeTraceRow!.length > 0) { 476 sp.tabCpuFreq!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 477 sp.tabCpuState!.rangeTraceRow = sp.rangeSelect.rangeTraceRow; 478 } 479 let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search'); 480 if (sp.rangeSelect.isMouseDown && search?.isClearValue) { 481 spSystemTraceDocumentOnMouseMoveMouseDown(sp, search); 482 } else { 483 spSystemTraceDocumentOnMouseMoveMouseUp(sp, rows, ev); 484 } 485} 486 487function handleMouseInTimeShaft(sp: SpSystemTrace, ev: MouseEvent): boolean | undefined { 488 let isMouseInTimeShaft = sp.timerShaftEL?.containPoint(ev); 489 if (isMouseInTimeShaft) { 490 sp.tipEL!.style.display = 'none'; 491 sp.hoverStructNull(); 492 } 493 return isMouseInTimeShaft; 494} 495 496export function spSystemTraceDocumentOnMouseMove(sp: SpSystemTrace, ev: MouseEvent): void { 497 //@ts-ignore 498 if (!sp.loadTraceCompleted || (window as unknown).flagInputFocus || !sp.mouseEventEnable) { 499 return; 500 } 501 //@ts-ignore 502 if ((window as unknown).collectResize) { 503 sp.style.cursor = 'row-resize'; 504 sp.cancelDrag(); 505 return; 506 } 507 if (sp.isWASDKeyPress()) { 508 sp.hoverFlag = null; 509 ev.preventDefault(); 510 return; 511 } 512 if (ev.ctrlKey && ev.button === 0 && SpSystemTrace.isMouseLeftDown) { 513 // 计算当前tab组件的高度 514 let tabHeight: number = 515 sp.shadowRoot?.querySelector('trace-sheet')!.shadowRoot?.querySelector('lit-tabs')!.clientHeight! + 1; 516 // 计算当前屏幕内高与鼠标位置坐标高度的差值 517 let diffHeight: number = window.innerHeight - ev.clientY; 518 // 如果差值大于面板高度,意味着鼠标位于泳道区域,可以通过ctrl+鼠标左键移动。否则不予生效 519 if (diffHeight > tabHeight) { 520 sp.translateByMouseMove(ev); 521 } else { 522 // 若鼠标位于tab面板区,则将其中标志位置成false 523 SpSystemTrace.isMouseLeftDown = false; 524 } 525 } 526 sp.inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 527 //@ts-ignore 528 if ((window as unknown).isSheetMove || sp.isMouseInSheet(ev)) { 529 sp.hoverStructNull(); 530 sp.tipEL!.style.display = 'none'; 531 return; 532 } 533 let isMouseInTimeShaft = handleMouseInTimeShaft(sp, ev); 534 let rows = sp.visibleRows; 535 sp.timerShaftEL?.documentOnMouseMove(ev, sp); 536 537 if (isMouseInTimeShaft) { 538 return; 539 } 540 handleActions(sp, rows, ev); 541} 542 543export function spSystemTraceDocumentOnMouseMoveMouseDown(sp: SpSystemTrace, search: LitSearch): void { 544 sp.refreshCanvas(true, 'sp move down'); 545 if (TraceRow.rangeSelectObject) { 546 if (search && search.searchValue !== '') { 547 search.clear(); 548 search.valueChangeHandler?.(''); 549 } 550 } 551} 552 553function spSystemTraceDocumentOnMouseMoveMouseUp( 554 sp: SpSystemTrace, //@ts-ignore 555 rows: Array<TraceRow<unknown>>, 556 ev: MouseEvent 557): void { 558 if (!sp.rowsPaneEL!.containPoint(ev, { left: 248 })) { 559 sp.hoverStructNull(); 560 } 561 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 562 const transformY = transformYMatch![1]; 563 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 564 // @ts-ignore 565 let memTr = rows.filter((item: unknown) => item.rowType === TraceRow.ROW_TYPE_MEM); 566 rows 567 .filter((it) => it.focusContain(ev, sp.inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === sp.inFavoriteArea) 568 .filter((it) => { 569 if (it.collect) { 570 return true; 571 } else { 572 return ( 573 it.getBoundingClientRect().bottom + it.getBoundingClientRect().height > 574 sp.favoriteChartListEL!.getBoundingClientRect().bottom 575 ); 576 } 577 }) 578 .forEach((tr): void => { 579 if (tr.rowType !== TraceRow.ROW_TYPE_CPU) { 580 CpuStruct.hoverCpuStruct = undefined; 581 } 582 if (tr.rowType !== TraceRow.ROW_TYPE_MEM) { 583 ProcessMemStruct.hoverProcessMemStruct = undefined; 584 memTr.forEach((i: unknown) => { 585 // @ts-ignore 586 i.focusHandler(ev); 587 }); 588 } 589 if (sp.currentRowType !== tr.rowType) { 590 sp.currentRowType = tr.rowType || ''; 591 } 592 tr.findHoverStruct?.(); 593 tr.focusHandler?.(ev); 594 }); 595 requestAnimationFrame(() => sp.refreshCanvas(true, 'sp move up')); 596} 597 598export function spSystemTraceDocumentOnMouseOut(sp: SpSystemTrace, ev: MouseEvent): void { 599 if (!sp.loadTraceCompleted) { 600 return; 601 } 602 CpuStruct.hoverCpuStruct = undefined; 603 TraceRow.isUserInteraction = false; 604 SpSystemTrace.isMouseLeftDown = false; 605 if (sp.isMouseInSheet(ev)) { 606 return; 607 } 608 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 609 sp.rangeSelect.mouseOut(ev); 610 sp.timerShaftEL?.documentOnMouseOut(ev); 611 } 612} 613 614export function spSystemTraceDocumentOnKeyPress(this: unknown, sp: SpSystemTrace, ev: KeyboardEvent): void { 615 SpSystemTrace.isKeyUp = false; 616 if (!sp.loadTraceCompleted || SpSystemTrace.isAiAsk) { 617 return; 618 } 619 let keyPress = ev.key.toLocaleLowerCase(); 620 TraceRow.isUserInteraction = true; 621 if (sp.isMousePointInSheet) { 622 return; 623 } 624 sp.observerScrollHeightEnable = false; 625 if (sp.keyboardEnable) { 626 if (keyPress === 'm') { 627 if (sp.selectFlag) { 628 sp.selectFlag!.selected = false; 629 } 630 sp.slicestime = sp.setSLiceMark(ev.shiftKey); 631 if (sp.slicestime) { 632 if (TraceRow.rangeSelectObject) { 633 let showTab = sp.getShowTab(); 634 sp.traceSheetEL 635 ?.displayTab<TabPaneCurrent>('tabpane-current', ...showTab) 636 .setCurrentSlicesTime(sp.slicestime); 637 } else { 638 sp.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(sp.slicestime); 639 } 640 } 641 } 642 if (keyPress === 'f') { 643 let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search'); 644 if (search && search.searchValue !== '' && sp.currentRow !== undefined) { 645 sp.currentRow = undefined; 646 } 647 let isSelectSliceOrFlag = false; 648 // 设置当前选中的slicetime 649 let selectSlice: unknown = undefined; 650 sp._slicesList.forEach((slice: { selected: boolean }): void => { 651 if (slice.selected) { 652 selectSlice = slice; 653 } 654 }); 655 if (!!selectSlice) { 656 //@ts-ignore 657 sp.currentSlicesTime.startTime = selectSlice.startTime; 658 //@ts-ignore 659 sp.currentSlicesTime.endTime = selectSlice.endTime; 660 isSelectSliceOrFlag = true; 661 } 662 663 if (sp.selectFlag && sp.selectFlag.selected) { 664 sp.currentSlicesTime.startTime = sp.selectFlag?.time; 665 sp.currentSlicesTime.endTime = sp.selectFlag?.time; 666 isSelectSliceOrFlag = true; 667 } 668 // 设置当前的slicesTime 669 !isSelectSliceOrFlag && sp.setCurrentSlicesTime(); 670 } 671 let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd'; 672 if (keyPressWASD) { 673 sp.keyPressMap.set(keyPress, true); 674 if (sp.rangeSelect.isMouseDown && sp.rangeSelect.drag) { 675 sp.rangeSelect.mouseUp(); 676 } 677 sp.hoverFlag = null; 678 } 679 sp.timerShaftEL!.documentOnKeyPress(ev, sp.currentSlicesTime); 680 if (keyPress === 'f') { 681 sp.verticalScrollToRow(); 682 } 683 } else { 684 sp.stopWASD(); 685 } 686} 687 688export function spSystemTraceDocumentOnMouseDown(sp: SpSystemTrace, ev: MouseEvent): void { 689 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 690 return; 691 } 692 if (sp.isWASDKeyPress()) { 693 ev.preventDefault(); 694 ev.stopPropagation(); 695 return; 696 } 697 if (ev.button === 0) { 698 SpSystemTrace.isMouseLeftDown = true; 699 if (ev.ctrlKey) { 700 ev.preventDefault(); 701 sp.style.cursor = 'move'; 702 sp.mouseCurrentPosition = ev.clientX; 703 return; 704 } 705 } 706 707 TraceRow.isUserInteraction = true; 708 if (sp.isMouseInSheet(ev)) { 709 return; 710 } 711 sp.observerScrollHeightEnable = false; 712 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 713 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 714 let y = ev.offsetY; 715 sp.timerShaftEL?.documentOnMouseDown(ev); 716 if (y > sp.timerShaftEL!.offsetHeight) { 717 sp.rangeSelect.mouseDown(ev); 718 sp.rangeSelect.drag = true; 719 let downRow = sp.visibleRows.find((row) => row.containPoint(ev)); 720 Utils.currentSelectTrace = downRow?.traceId; 721 } 722 // 如果鼠标摁下事件发生在traceRow范围或时间轴(sportRuler除外)范围内,清除上次点击调用栈产生的所有的三角旗子 723 // ev.offsetY:鼠标在SpSystemTrace元素的y轴偏移量 724 if ( 725 ev.offsetY > sp.timerShaftEL!.clientHeight || 726 ev.offsetY < sp.timerShaftEL!.clientHeight - sp.timerShaftEL!.sportRuler!.frame.height 727 ) { 728 sp.clearTriangle(sp.timerShaftEL!.sportRuler!.flagList); 729 } 730 } else { 731 sp.rangeSelect.drag = false; 732 } 733} 734 735function handleTimerShaftActions(ev: MouseEvent, sp: SpSystemTrace): void { 736 if (ev.offsetX > sp.timerShaftEL!.canvas!.offsetLeft) { 737 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 738 let y = ev.offsetY; 739 if ( 740 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 741 x > (TraceRow.rangeSelectObject?.startX || 0) && 742 x < (TraceRow.rangeSelectObject?.endX || 0) 743 ) { 744 let findSlicestime = sp.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子 745 if (!findSlicestime) { 746 // 如果没有找到帽子,则绘制一个旗子 747 let time = Math.round( 748 (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / sp.timerShaftEL!.canvas!.offsetWidth + 749 TraceRow.range?.startNS! 750 ); 751 sp.timerShaftEL!.sportRuler!.drawTriangle(time, 'squre'); 752 } 753 } 754 } 755} 756 757export function spSystemTraceDocumentOnMouseUp(sp: SpSystemTrace, ev: MouseEvent): void { 758 //@ts-ignore 759 if ((window as unknown).collectResize) { 760 return; 761 } 762 if (!sp.loadTraceCompleted || !sp.mouseEventEnable) { 763 return; 764 } 765 if (sp.isWASDKeyPress()) { 766 ev.preventDefault(); 767 ev.stopPropagation(); 768 return; 769 } 770 SpSystemTrace.isMouseLeftDown = false; 771 if (ev.ctrlKey) { 772 ev.preventDefault(); 773 sp.offsetMouse = 0; 774 sp.mouseCurrentPosition = 0; 775 sp.style.cursor = 'default'; 776 return; 777 } 778 TraceRow.isUserInteraction = false; 779 sp.rangeSelect.isMouseDown = false; 780 //@ts-ignore 781 if ((window as unknown).isSheetMove) { 782 return; 783 } 784 if (sp.isMouseInSheet(ev)) { 785 return; 786 } 787 handleTimerShaftActions(ev, sp); 788 if (!SportRuler.isMouseInSportRuler) { 789 sp.rangeSelect.mouseUp(ev); 790 } 791 sp.timerShaftEL?.documentOnMouseUp(ev); 792} 793 794export function spSystemTraceDocumentOnKeyUp(sp: SpSystemTrace, ev: KeyboardEvent): void { 795 SpSystemTrace.isKeyUp = true; 796 if (sp.times.size > 0) { 797 for (let timerId of sp.times) { 798 clearTimeout(timerId); 799 } 800 } 801 let flag: boolean = sp.parentElement 802 ?.querySelector('sp-record-trace')! 803 .shadowRoot?.querySelector('lit-main-menu-item[icon="file-config"]')! 804 .hasAttribute('back')!; 805 if (ev.key.toLocaleLowerCase() === String.fromCharCode(47) && !flag) { 806 if (SpSystemTrace.keyboardFlar) { 807 document 808 .querySelector('body > sp-application')! 809 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'visible'; 810 SpSystemTrace.keyboardFlar = false; 811 } else { 812 document 813 .querySelector('body > sp-application')! 814 .shadowRoot!.querySelector<SpKeyboard>('#sp-keyboard')!.style.visibility = 'hidden'; 815 SpSystemTrace.keyboardFlar = true; 816 } 817 } 818 if (!sp.loadTraceCompleted) { 819 return; 820 } 821 let flagsItem = window.localStorage.getItem(FlagsConfig.FLAGS_CONFIG_KEY); 822 let flagsItemJson = JSON.parse(flagsItem!); 823 if (flagsItemJson.VSync === 'Enabled') { 824 sp.keyboardEnable && enableVSync(false, ev, () => sp.refreshCanvas(true, 'sp key up')); 825 } 826 let keyPress = ev.key.toLocaleLowerCase(); 827 if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') { 828 sp.keyPressMap.set(keyPress, false); 829 } 830 TraceRow.isUserInteraction = false; 831 sp.observerScrollHeightEnable = false; 832 sp.keyboardEnable && sp.timerShaftEL!.documentOnKeyUp(ev); 833 if (ev.code === 'Enter' || ev.code === 'NumpadEnter') { 834 document.removeEventListener('keydown', sp.documentOnKeyDown); 835 if (ev.shiftKey) { 836 sp.dispatchEvent( 837 new CustomEvent('trace-previous-data', { 838 detail: {}, 839 composed: false, 840 }) 841 ); 842 } else { 843 sp.dispatchEvent( 844 new CustomEvent('trace-next-data', { 845 detail: {}, 846 composed: false, 847 }) 848 ); 849 } 850 document.addEventListener('keydown', sp.documentOnKeyDown); 851 } 852 853 if (ev.ctrlKey) { 854 spSystemTraceDocumentOnKeyUpCtrlKey(keyPress, sp, ev); 855 } 856} 857 858function spSystemTraceDocumentOnKeyUpCtrlKey(keyPress: string, sp: SpSystemTrace, ev: KeyboardEvent): void { 859 if (keyPress === 'b') { 860 let menuBox = document 861 .querySelector('body > sp-application')! 862 .shadowRoot?.querySelector('#main-menu') as LitMainMenu; 863 let searchBox = document 864 .querySelector('body > sp-application') 865 ?.shadowRoot?.querySelector('div > div.search-vessel') as HTMLDivElement; 866 let appContent = document 867 .querySelector('body > sp-application') 868 ?.shadowRoot?.querySelector('div > #app-content') as HTMLDivElement; 869 let rowPane = appContent 870 ?.querySelector('#sp-system-trace') 871 ?.shadowRoot?.querySelector('div > div.rows-pane') as HTMLDivElement; 872 let timerShaft = appContent 873 ?.querySelector('#sp-system-trace') 874 ?.shadowRoot?.querySelector('div > timer-shaft-element') as HTMLDivElement; 875 let spChartList = appContent 876 ?.querySelector('#sp-system-trace') 877 ?.shadowRoot?.querySelector('div > sp-chart-list') as HTMLDivElement; 878 let canvasEle = spChartList.shadowRoot?.querySelector('canvas') as unknown as HTMLDivElement; 879 let sidebarButton = searchBox!.querySelector('div > div.sidebar-button') as HTMLDivElement; 880 let importConfigDiv = searchBox!.querySelector('div > #import-key-path') as HTMLDivElement; 881 if (menuBox.style.zIndex! === '2000' || searchBox!.style.display !== 'none') { 882 SpSystemTrace.isHiddenMenu = true; 883 menuBox.style.width = '0px'; 884 menuBox.style.display = 'flex'; 885 menuBox.style.zIndex = '0'; 886 sidebarButton.style.width = '48px'; 887 importConfigDiv!.style.left = '45px'; 888 searchBox!.style.display = 'none'; 889 rowPane.style.maxHeight = '100%'; 890 } else { 891 SpSystemTrace.isHiddenMenu = false; 892 menuBox.style.width = '248px'; 893 menuBox.style.zIndex = '2000'; 894 menuBox.style.display = 'flex'; 895 sidebarButton.style.width = '0px'; 896 importConfigDiv!.style.left = '5px'; 897 searchBox!.style.display = ''; 898 rowPane.style.maxHeight = '100%'; 899 } 900 } 901 if (keyPress === '[' && sp._slicesList.length > 1) { 902 sp.selectFlag = undefined; 903 sp.MarkJump(sp._slicesList, 'slice', 'previous', ev); 904 } else if (keyPress === ',' && sp._flagList.length > 1) { 905 sp.MarkJump(sp._flagList, 'flag', 'previous', ev); 906 } else if (keyPress === ']' && sp._slicesList.length > 1) { 907 sp.selectFlag = undefined; 908 sp.MarkJump(sp._slicesList, 'slice', 'next', ev); 909 } else if (keyPress === '.' && sp._flagList.length > 1) { 910 sp.MarkJump(sp._flagList, 'flag', 'next', ev); 911 } else { 912 return; 913 } 914} 915 916function handleClickActions(sp: SpSystemTrace, x: number, y: number, ev: MouseEvent): void { 917 if ( 918 !( 919 sp.timerShaftEL!.sportRuler!.frame.contains(x, y) && 920 x > (TraceRow.rangeSelectObject?.startX || 0) && 921 x < (TraceRow.rangeSelectObject?.endX || 0) 922 ) 923 ) { 924 const transformYMatch = sp.canvasPanel?.style.transform.match(/\((\d+)[^\)]+\)/); 925 const transformY = transformYMatch![1]; 926 let inFavoriteArea = sp.favoriteChartListEL?.containPoint(ev); 927 let favoriteHeight = sp.favoriteChartListEL!.getBoundingClientRect().height; 928 let rows = sp.visibleRows.filter((it) => 929 it.focusContain(ev, inFavoriteArea!, Number(transformY), favoriteHeight) && it.collect === inFavoriteArea); 930 if (JankStruct.delJankLineFlag) { 931 sp.removeLinkLinesByBusinessType('janks'); 932 } 933 let strict = true; 934 let offset = false; 935 if ( 936 rows[0] && 937 (rows[0].rowType === TraceRow.ROW_TYPE_FRAME_DYNAMIC || rows[0].rowType === TraceRow.ROW_TYPE_FRAME_SPACING) 938 ) { 939 strict = false; 940 offset = true; 941 } 942 if (rows && rows[0] && (rows[0].getHoverStruct(strict, offset) || 943 (rows[0].rowType === TraceRow.ROW_TYPE_GPU_COUNTER && rows[0].getHoverStruct(false)))) { 944 sp.onClickHandler(rows[0]!.rowType!, rows[0], rows[0].getHoverStruct(strict, offset)); 945 sp.documentOnMouseMove(ev); 946 } else { 947 sp.clickEmptyArea(); 948 } 949 } 950} 951 952export function spSystemTraceDocumentOnClick(sp: SpSystemTrace, ev: MouseEvent): void { 953 if (!sp.loadTraceCompleted) { 954 return; 955 } 956 if (sp.isWASDKeyPress()) { 957 sp.hoverFlag = null; 958 ev.preventDefault(); 959 ev.stopPropagation(); 960 return; 961 } 962 //@ts-ignore 963 if ((window as unknown).isSheetMove) { 964 return; 965 } 966 if (sp.isMouseInSheet(ev)) { 967 return; 968 } 969 //@ts-ignore 970 if ((window as unknown).isPackUpTable) { 971 //@ts-ignore 972 (window as unknown).isPackUpTable = false; 973 return; 974 } 975 let x = ev.offsetX - sp.timerShaftEL!.canvas!.offsetLeft; 976 let y = ev.offsetY; 977 if (sp.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) { 978 sp.clickEmptyArea(); 979 return; 980 } 981 if (sp.rangeSelect.isDrag()) { 982 return; 983 } 984 handleClickActions(sp, x, y, ev); 985 ev.preventDefault(); 986} 987 988export function spSystemTraceDocumentOnKeyDown(sp: SpSystemTrace, ev: KeyboardEvent): void { 989 document.removeEventListener('keyup', sp.documentOnKeyUp); 990 sp.debounce(sp.continueSearch, 250, ev)(); 991 document.addEventListener('keyup', sp.documentOnKeyUp); 992} 993