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 {assertDefined} from 'common/assert_utils'; 18import {perfetto} from 'protos/surfaceflinger/latest/static'; 19import {android} from 'protos/surfaceflinger/udc/static'; 20import {LazyPropertiesStrategyType} from 'trace/tree_node/properties_provider'; 21import {PropertyTreeBuilderFromProto} from 'trace/tree_node/property_tree_builder_from_proto'; 22import {PropertyTreeNode} from 'trace/tree_node/property_tree_node'; 23import {AddCompositionType} from './operations/add_composition_type'; 24import {AddDisplayProperties} from './operations/add_display_properties'; 25import {AddExcludesCompositionState} from './operations/add_excludes_composition_state'; 26import {AddVerboseFlags} from './operations/add_verbose_flags'; 27import {UpdateTransforms} from './operations/update_transforms'; 28 29export class ParserSfUtils { 30 static readonly EAGER_PROPERTIES = [ 31 'id', 32 'name', 33 'type', 34 'parent', 35 'children', 36 'bounds', 37 'transform', 38 'position', 39 'requestedTransform', 40 'requestedPosition', 41 'bufferTransform', 42 'inputWindowInfo', 43 'flags', 44 'z', 45 'cornerRadius', 46 'layerStack', 47 'isOpaque', 48 'activeBuffer', 49 'visibleRegion', 50 'color', 51 'isRelativeOf', 52 'zOrderRelativeOf', 53 'screenBounds', 54 'shadowRadius', 55 'backgroundBlurRadius', 56 'hwcCompositionType', 57 ]; 58 59 static readonly DENYLIST_PROPERTIES = [ 60 'length', 61 'prototype', 62 'ref', 63 'parent', 64 'timestamp', 65 'layers', 66 'children', 67 'name', 68 ]; 69 70 static readonly OPERATIONS = { 71 UpdateTransforms: new UpdateTransforms(), 72 AddVerboseFlags: new AddVerboseFlags(), 73 AddExcludesCompositionStateTrue: new AddExcludesCompositionState(true), 74 AddExcludesCompositionStateFalse: new AddExcludesCompositionState(false), 75 AddDisplayProperties: new AddDisplayProperties(), 76 AddCompositionType: new AddCompositionType(), 77 }; 78 79 static makeEagerPropertiesTree( 80 layer: android.surfaceflinger.ILayerProto | perfetto.protos.ILayerProto, 81 duplicateCount: number, 82 ): PropertyTreeNode { 83 const denyList: string[] = []; 84 let obj = layer; 85 do { 86 Object.getOwnPropertyNames(obj).forEach((it) => { 87 if (!ParserSfUtils.EAGER_PROPERTIES.includes(it)) denyList.push(it); 88 }); 89 obj = Object.getPrototypeOf(obj); 90 } while (obj); 91 92 return new PropertyTreeBuilderFromProto() 93 .setData(layer) 94 .setRootId(assertDefined(layer.id)) 95 .setRootName(assertDefined(layer.name)) 96 .setDenyList(denyList) 97 .setDuplicateCount(duplicateCount) 98 .build(); 99 } 100 101 static makeEntryEagerPropertiesTree( 102 entry: 103 | android.surfaceflinger.ILayersTraceProto 104 | perfetto.protos.ILayersSnapshotProto, 105 ): PropertyTreeNode { 106 const denyList: string[] = []; 107 let obj = entry; 108 do { 109 Object.getOwnPropertyNames(obj).forEach((it) => { 110 if (it !== 'displays') denyList.push(it); 111 }); 112 obj = Object.getPrototypeOf(obj); 113 } while (obj); 114 115 return new PropertyTreeBuilderFromProto() 116 .setData(entry) 117 .setRootId('LayerTraceEntry') 118 .setRootName('root') 119 .setDenyList(denyList) 120 .build(); 121 } 122 123 static makeLayerLazyPropertiesStrategy( 124 layer: android.surfaceflinger.ILayerProto | perfetto.protos.ILayerProto, 125 duplicateCount: number, 126 ): LazyPropertiesStrategyType { 127 return async () => { 128 return new PropertyTreeBuilderFromProto() 129 .setData(layer) 130 .setRootId(assertDefined(layer.id)) 131 .setRootName(assertDefined(layer.name)) 132 .setDenyList( 133 ParserSfUtils.EAGER_PROPERTIES.concat( 134 ParserSfUtils.DENYLIST_PROPERTIES, 135 ), 136 ) 137 .setDuplicateCount(duplicateCount) 138 .build(); 139 }; 140 } 141 142 static makeEntryLazyPropertiesStrategy( 143 entry: 144 | android.surfaceflinger.ILayersTraceProto 145 | perfetto.protos.ILayersSnapshotProto, 146 ): LazyPropertiesStrategyType { 147 return async () => { 148 return new PropertyTreeBuilderFromProto() 149 .setData(entry) 150 .setRootId('LayerTraceEntry') 151 .setRootName('root') 152 .setDenyList(ParserSfUtils.DENYLIST_PROPERTIES) 153 .build(); 154 }; 155 } 156} 157