1 2/* 3 * Copyright (C) 2022 Huawei Device Co., Ltd. 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16import { ColorUtils } from '../../component/trace/base/ColorUtils'; 17import { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon'; 18import { TraceRow } from '../../component/trace/base/TraceRow'; 19import { drawString, Rect, ns2x } from './ProcedureWorkerCommon'; 20import { SpSegmentationChart } from '../../component/chart/SpSegmentationChart'; 21import { Flag } from '../../component/trace/timer-shaft/Flag'; 22import { CpuFreqExtendStruct } from './ProcedureWorkerFreqExtend'; 23import { AllstatesStruct } from './ProcedureWorkerAllStates'; 24export class BinderRender extends Render { 25 renderMainThread( 26 freqReq: { 27 context: CanvasRenderingContext2D; 28 useCache: boolean; 29 type: string; 30 }, 31 row: TraceRow<BinderStruct> 32 ) { 33 let binderList = row.dataList; 34 let binderFilter = row.dataListCache; 35 dataFilterHandler(binderList, binderFilter, { 36 startKey: 'startNS', 37 durKey: 'dur', 38 startNS: TraceRow.range?.startNS ?? 0, 39 endNS: TraceRow.range?.endNS ?? 0, 40 totalNS: TraceRow.range?.totalNS ?? 0, 41 frame: row.frame, 42 paddingTop: 5, 43 useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), 44 }); 45 let find = false; 46 BinderStruct.hoverCpuFreqStruct = undefined; 47 if (SpSegmentationChart.tabHoverObj && SpSegmentationChart.tabHoverObj.key !== '') { 48 if (!SpSegmentationChart.trace.isMousePointInSheet) { 49 SpSegmentationChart.tabHoverObj = { key: '', cycle: -1 }; 50 } 51 if (SpSegmentationChart.tabHoverObj.key === freqReq.type) { 52 for (let re of binderFilter) { 53 if (!row.isHover && re.cycle === SpSegmentationChart.tabHoverObj.cycle) { 54 BinderStruct.hoverCpuFreqStruct = re; 55 find = true; 56 } 57 BinderStruct.draw(freqReq.context, re); 58 } 59 // dur太小,从datalist里面找 60 if (!find) { 61 let hoverData = binderList.filter(v => { 62 return v.cycle === SpSegmentationChart.tabHoverObj.cycle; 63 })[0]; 64 if (hoverData) { 65 let pointX: number = ns2x( 66 hoverData.startNS || 0, 67 TraceRow.range!.startNS, 68 TraceRow.range!.endNS, 69 TraceRow.range!.totalNS, 70 new Rect(0, 0, TraceRow.FRAME_WIDTH, 0) 71 ); 72 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = new Flag( 73 Math.floor(pointX), 74 0, 75 0, 76 0, 77 hoverData.startNS, 78 '#666666', 79 '', 80 true, 81 '' 82 ); 83 } 84 } 85 } else { 86 for (let re of binderFilter) { 87 BinderStruct.draw(freqReq.context, re); 88 } 89 } 90 } else { 91 for (let re of binderFilter) { 92 if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 93 BinderStruct.hoverCpuFreqStruct = re; 94 find = true; 95 } 96 BinderStruct.draw(freqReq.context, re); 97 } 98 } 99 if (!find && 100 SpSegmentationChart.tabHoverObj && SpSegmentationChart.tabHoverObj.key === '' && 101 CpuFreqExtendStruct.hoverStruct === undefined && !AllstatesStruct.hoverThreadStruct) { 102 BinderStruct.hoverCpuFreqStruct = undefined; 103 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = undefined; 104 find = false; 105 } 106 freqReq.context.closePath(); 107 } 108} 109export class BinderStruct extends BaseStruct { 110 static hoverCpuFreqStruct: BinderStruct | undefined; 111 static selectCpuFreqStruct: BinderStruct | undefined; 112 static maxHeight: number = 0; 113 static hoverCycle: number = -1; 114 static isTabHover: boolean = false; 115 value: number = 0; 116 cycle: number = 0; 117 startNS: number = 0; 118 dur: number | undefined; //自补充,数据库没有返回 119 name: string | undefined; 120 depth: number = 0; 121 static draw(freqContext: CanvasRenderingContext2D, data: BinderStruct) { 122 if (data.frame) { 123 let color = ''; 124 if (data.name === 'binder transaction') { 125 color = '#e86b6a'; 126 } 127 if (data.name === 'binder transaction async') { 128 color = '#36baa4'; 129 } 130 if (data.name === 'binder reply') { 131 color = '#8770d3'; 132 } 133 if (data.name === 'binder async rcv') { 134 color = '#0cbdd4'; 135 } 136 freqContext.fillStyle = color; 137 if ( 138 data === BinderStruct.hoverCpuFreqStruct || 139 data === BinderStruct.selectCpuFreqStruct 140 ) { 141 let pointX: number = ns2x( 142 data.startNS || 0, 143 TraceRow.range!.startNS, 144 TraceRow.range!.endNS, 145 TraceRow.range!.totalNS, 146 new Rect(0, 0, TraceRow.FRAME_WIDTH, 0) 147 ); 148 if (BinderStruct.isTabHover || data === BinderStruct.hoverCpuFreqStruct) { 149 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = new Flag( 150 Math.floor(pointX), 151 0, 152 0, 153 0, 154 data.startNS, 155 '#666', 156 '', 157 true, 158 '' 159 ); 160 freqContext.globalAlpha = 1; 161 freqContext.lineWidth = 1; 162 freqContext.fillRect( 163 data.frame.x, 164 BinderStruct.maxHeight * 20 - data.depth * 20 + 20, 165 data.frame.width, 166 data.value * 20 167 ); 168 } 169 } else { 170 freqContext.globalAlpha = 0.6; 171 freqContext.lineWidth = 1; 172 freqContext.fillRect( 173 data.frame.x, 174 BinderStruct.maxHeight * 20 - data.depth * 20 + 20, 175 data.frame.width, 176 data.value * 20 177 ); 178 } 179 if (data.frame.width > 8) { 180 freqContext.lineWidth = 1; 181 freqContext.fillStyle = ColorUtils.funcTextColor( 182 ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.name || '', 0, ColorUtils.FUNC_COLOR.length)] 183 ); 184 freqContext.textBaseline = 'middle'; 185 drawString( 186 freqContext, 187 `${data.name || ''}`, 188 6, 189 new Rect(data.frame.x, BinderStruct.maxHeight * 20 - data.depth * 20 + 20, data.frame.width, data.value * 20), 190 data 191 ); 192 } 193 freqContext.globalAlpha = 1.0; 194 freqContext.lineWidth = 1; 195 } 196 } 197} 198