1/* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 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 */ 16 17import {assertTrue} from 'common/assert_utils'; 18import {AbsoluteEntryIndex, EntriesRange} from 'trace/trace'; 19import {WasmEngineProxy} from 'trace_processor/wasm_engine_proxy'; 20import {FakeProto, FakeProtoBuilder} from './fake_proto_builder'; 21 22export class Utils { 23 static async queryEntry( 24 traceProcessor: WasmEngineProxy, 25 tableName: string, 26 entryIndexToRowIdMap: number[], 27 entryIndex: AbsoluteEntryIndex, 28 ): Promise<FakeProto> { 29 const rowId = entryIndexToRowIdMap[entryIndex]; 30 const sql = ` 31 SELECT 32 tbl.id, 33 args.key, 34 args.value_type, 35 args.int_value, 36 args.string_value, 37 args.real_value 38 FROM ${tableName} AS tbl 39 INNER JOIN args ON tbl.arg_set_id = args.arg_set_id 40 WHERE tbl.id = ${rowId}; 41 `; 42 const result = await traceProcessor.query(sql).waitAllRows(); 43 44 const builder = new FakeProtoBuilder(); 45 for (const it = result.iter({}); it.valid(); it.next()) { 46 builder.addArg( 47 it.get('key') as string, 48 it.get('value_type') as string, 49 it.get('int_value') as bigint | undefined, 50 it.get('real_value') as number | undefined, 51 it.get('string_value') as string | undefined, 52 ); 53 } 54 return builder.build(); 55 } 56 57 static async queryVsyncId( 58 traceProcessor: WasmEngineProxy, 59 tableName: string, 60 entryIndexToRowIdMap: number[], 61 entriesRange: EntriesRange, 62 ): Promise<Array<bigint>> { 63 let minRowId = Number.MAX_VALUE; 64 let maxRowId = Number.MIN_VALUE; 65 for ( 66 let entryIndex = entriesRange.start; 67 entryIndex < entriesRange.end; 68 ++entryIndex 69 ) { 70 const rowId = entryIndexToRowIdMap[entryIndex]; 71 minRowId = Math.min(minRowId, rowId); 72 maxRowId = Math.max(maxRowId, rowId); 73 } 74 75 const sql = ` 76 SELECT 77 tbl.id, 78 args.key, 79 args.value_type, 80 args.int_value 81 FROM ${tableName} AS tbl 82 INNER JOIN args ON tbl.arg_set_id = args.arg_set_id 83 WHERE 84 tbl.id BETWEEN ${minRowId} AND ${maxRowId} 85 AND args.key = 'vsync_id' 86 ORDER BY tbl.id; 87 `; 88 89 const result = await traceProcessor.query(sql).waitAllRows(); 90 91 const vsyncIdOrderedByRow: Array<bigint> = []; 92 for (const it = result.iter({}); it.valid(); it.next()) { 93 const value = it.get('int_value') as bigint | undefined; 94 const valueType = it.get('value_type') as string; 95 assertTrue( 96 valueType === 'uint' || valueType === 'int', 97 () => 'expected vsyncid to have integer type', 98 ); 99 vsyncIdOrderedByRow.push(value ?? -1n); 100 } 101 102 const vsyncIdOrderedByEntry: Array<bigint> = []; 103 for ( 104 let entryIndex = entriesRange.start; 105 entryIndex < entriesRange.end; 106 ++entryIndex 107 ) { 108 const rowId = entryIndexToRowIdMap[entryIndex]; 109 const vsyncId = vsyncIdOrderedByRow[rowId - minRowId]; 110 vsyncIdOrderedByEntry.push(vsyncId); 111 } 112 113 return vsyncIdOrderedByEntry; 114 } 115} 116