• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 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 
17 package com.android.server.wm.traces.common.layers
18 
19 import com.android.server.wm.traces.common.Rect
20 import com.android.server.wm.traces.common.RectF
21 
22 /**
23  * Represents a single Layer trace entry.
24  *
25  * This is a generic object that is reused by both Flicker and Winscope and cannot
26  * access internal Java/Android functionality
27  *
28  **/
29 open class LayerTraceEntry constructor(
30     override val timestamp: Long,
31     override val hwcBlob: String,
32     override val where: String,
33     override val displays: Array<Display>,
34     _rootLayers: Array<Layer>
35 ) : BaseLayerTraceEntry() {
36     override val flattenedLayers: Array<Layer> = fillFlattenedLayers(_rootLayers)
37 
38     private fun fillFlattenedLayers(rootLayers: Array<Layer>): Array<Layer> {
39         val opaqueLayers = mutableListOf<Layer>()
40         val transparentLayers = mutableListOf<Layer>()
41         val layers = mutableListOf<Layer>()
42         // some of the flickerlib traces are old and don't have the display data on the trace
43         val mainDisplaySize = displays.firstOrNull { !it.isVirtual }?.layerStackSpace ?: Rect.EMPTY
44         val roots = rootLayers.fillOcclusionState(
45             opaqueLayers, transparentLayers, mainDisplaySize.toRectF()).toMutableList()
46         while (roots.isNotEmpty()) {
47             val layer = roots.removeAt(0)
48             layers.add(layer)
49             roots.addAll(layer.children)
50         }
51         return layers.toTypedArray()
52     }
53 
54     private fun Array<Layer>.topDownTraversal(): List<Layer> {
55         return this
56                 .sortedBy { it.z }
57                 .flatMap { it.topDownTraversal() }
58     }
59 
60     private fun Layer.topDownTraversal(): List<Layer> {
61         val traverseList = mutableListOf(this)
62 
63         this.children.sortedBy { it.z }
64                 .forEach { childLayer ->
65                     traverseList.addAll(childLayer.topDownTraversal())
66                 }
67 
68         return traverseList
69     }
70 
71     private fun Array<Layer>.fillOcclusionState(
72         opaqueLayers: MutableList<Layer>,
73         transparentLayers: MutableList<Layer>,
74         displaySize: RectF
75     ): Array<Layer> {
76         val traversalList = topDownTraversal().reversed()
77 
78         traversalList.forEach { layer ->
79             val visible = layer.isVisible
80 
81             if (visible) {
82                 val occludedBy = opaqueLayers
83                     .filter { it.contains(layer, displaySize) && !it.hasRoundedCorners }
84                     .toTypedArray()
85                 layer.addOccludedBy(occludedBy)
86                 val partiallyOccludedBy = opaqueLayers
87                     .filter { it.overlaps(layer, displaySize) && it !in layer.occludedBy }
88                     .toTypedArray()
89                 layer.addPartiallyOccludedBy(partiallyOccludedBy)
90                 val coveredBy = transparentLayers
91                     .filter { it.overlaps(layer, displaySize) }
92                     .toTypedArray()
93                 layer.addCoveredBy(coveredBy)
94 
95                 if (layer.isOpaque) {
96                     opaqueLayers.add(layer)
97                 } else {
98                     transparentLayers.add(layer)
99                 }
100             }
101         }
102 
103         return this
104     }
105 }