1/* 2 * Copyright (C) 2024 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 {HierarchyTreeNode} from 'trace/tree_node/hierarchy_tree_node'; 19 20export class LayerExtractor { 21 static extractLayersTopToBottom( 22 layer: HierarchyTreeNode, 23 ): HierarchyTreeNode[] { 24 const traverseList: HierarchyTreeNode[] = []; 25 26 const sortedZChildren = layer 27 .getRelativeChildren() 28 .concat( 29 layer.getAllChildren().filter((child) => child.getZParent() === layer), 30 ) 31 .sort((a, b) => LayerExtractor.compareByZAndLayerId(a, b)); 32 33 if (layer.isRoot()) { 34 sortedZChildren.forEach((c) => { 35 traverseList.push(...LayerExtractor.extractLayersTopToBottom(c)); 36 }); 37 } else { 38 const layerZ = LayerExtractor.getZ(layer); 39 const sortedZChildrenBelowRoot = sortedZChildren.filter( 40 (child) => LayerExtractor.getZ(child) < layerZ, 41 ); 42 const sortedZChildrenAboveRoot = sortedZChildren.filter( 43 (child) => LayerExtractor.getZ(child) >= layerZ, 44 ); 45 46 sortedZChildrenAboveRoot.forEach((c) => { 47 traverseList.push(...LayerExtractor.extractLayersTopToBottom(c)); 48 }); 49 traverseList.push(layer); 50 sortedZChildrenBelowRoot.forEach((c) => { 51 traverseList.push(...LayerExtractor.extractLayersTopToBottom(c)); 52 }); 53 } 54 return traverseList; 55 } 56 57 private static compareByZAndLayerId( 58 a: HierarchyTreeNode, 59 b: HierarchyTreeNode, 60 ): number { 61 const aZ = LayerExtractor.getZ(a); 62 const bZ = LayerExtractor.getZ(b); 63 64 if (aZ > bZ) return -1; 65 if (aZ < bZ) return 1; 66 67 // When z-order is the same, the layer with larger ID is on top 68 const aId = a.getEagerPropertyByName('id')?.getValue(); 69 const bId = b.getEagerPropertyByName('id')?.getValue(); 70 return aId < bId ? 1 : -1; 71 } 72 73 private static getZ(node: HierarchyTreeNode): number { 74 return assertDefined(node.getEagerPropertyByName('z')).getValue(); 75 } 76} 77